Advertisement
Guest User

Untitled

a guest
Apr 27th, 2020
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (ns pantrack.tape
  2.   (:require [clojure.string :as str]
  3.             [goog.events :as events]
  4.             [goog.history.EventType :as HistoryEventType])
  5.   (:import goog.history.Html5History
  6.            goog.history.Html5History.TokenTransformer
  7.            goog.Uri))
  8.  
  9. (defn- update-history! [h]
  10.   (doto h
  11.     (.setUseFragment false)
  12.     (.setPathPrefix
  13.      (str js/window.location.protocol "//"
  14.           js/window.location.host))
  15.     (.setEnabled true)))
  16.  
  17. (defn- set-retrieve-token! [t]
  18.   (set! (.. t -retrieveToken)
  19.         (fn [path-prefix location]
  20.           (str (.-pathname location) (.-search location)))))
  21.  
  22. (defn- set-create-url! [t]
  23.   (set! (.. t -createUrl)
  24.         (fn [token path-prefix location]
  25.           (str path-prefix token))))
  26.  
  27. (defn new-history
  28.   ([]
  29.    (new-history
  30.     (doto (TokenTransformer.)
  31.       set-retrieve-token!
  32.       set-create-url!)))
  33.   ([transformer]
  34.    (-> (Html5History. js/window transformer)
  35.        update-history!)))
  36.  
  37. (defn dispatch-if-client-route
  38.   [token match-fn dispatch-fn unmatched-fn]
  39.   (if (some? (match-fn token))
  40.     (dispatch-fn token)
  41.     (unmatched-fn token)))
  42.  
  43. (defprotocol ITape
  44.   (set-token! [this token] [this token title])
  45.   (replace-token! [this token] [this token title])
  46.   (get-token [this])
  47.   (start! [this])
  48.   (stop! [this]))
  49.  
  50. (defrecord Tape [history dispatch-fn match-fn
  51.                  unmatched-fn identity-fn event-keys]
  52.   ITape
  53.   (set-token! [_ token]
  54.     (. history (setToken token)))
  55.   (set-token! [_ token title]
  56.     (. history (setToken token title)))
  57.   (replace-token! [_ token]
  58.     (. history (replaceToken token)))
  59.   (replace-token! [_ token title]
  60.     (. history (replaceToken token title)))
  61.   (get-token [_]
  62.     (.getToken history))
  63.   (start! [this]
  64.     (doseq [key @event-keys]
  65.       (events/unlistenByKey key))
  66.     (reset! event-keys nil)
  67.  
  68.     (swap!
  69.      event-keys conj
  70.      (events/listen
  71.       history
  72.       HistoryEventType/NAVIGATE
  73.       (fn [e]
  74.         (dispatch-if-client-route
  75.          (.-token e) match-fn
  76.          dispatch-fn unmatched-fn))))
  77.  
  78.     (dispatch-if-client-route
  79.      (get-token this) match-fn
  80.      dispatch-fn unmatched-fn))
  81.   (stop! [_]
  82.     (doseq [key @event-keys]
  83.       (events/unlistenByKey key))
  84.     (reset! event-keys nil)
  85.     (.setEnabled history false)))
  86.  
  87. (defn new-tape [match-fn dispatch-fn unmatched-fn]
  88.   (map->Tape {:history (new-history)
  89.               :match-fn match-fn
  90.               :dispatch-fn dispatch-fn
  91.               :unmatched-fn unmatched-fn
  92.               :identity-fn identity
  93.               :event-keys (atom nil)}))
  94.  
  95. (defn uri->query [uri]
  96.   (let [query (.getQuery uri)]
  97.     (when-not (empty? query)
  98.       (str "?" query))))
  99.  
  100. (defn uri->fragment [uri]
  101.   (let [fragment (.getFragment uri)]
  102.     (when-not (empty? fragment)
  103.       (str "#" fragment))))
  104.  
  105. (defn map->params [query]
  106.   (let [params (map #(name %) (keys query))
  107.         values (vals query)
  108.         pairs (partition 2 (interleave params values))]
  109.     (str/join "&" (map #(clojure.string/join "=" %) pairs))))
  110.  
  111. (defn navigate!
  112.   ([tape]
  113.    (let [path (-> js/window .-location .-pathname)
  114.          query (-> js/window .-location .-search)
  115.          hash (-> js/window .-location .-hash)]
  116.      ((:dispatch-fn tape)
  117.       (str path query hash))))
  118.   ([tape route] (navigate! tape route {}))
  119.   ([tape route query]
  120.    (let [token (get-token tape)
  121.          old-route (first (str/split token "?"))
  122.          query-string (map->params
  123.                        (reduce-kv
  124.                         (fn [valid k v]
  125.                           (if v
  126.                             (assoc valid k v)
  127.                             valid))
  128.                         {} query))
  129.          with-params (if (empty? query-string)
  130.                        route
  131.                        (str route "?" query-string))]
  132.      (if (= old-route route)
  133.        (replace-token! tape with-params)
  134.        (set-token! tape with-params)))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement