2014-01-17 11:35:40 +00:00
|
|
|
(ns reagentdemo.page
|
|
|
|
(:require [reagent.core :as reagent :refer [atom partial]]
|
|
|
|
[reagent.debug :refer-macros [dbg]]
|
|
|
|
[clojure.string :as string]
|
|
|
|
[goog.events :as events])
|
|
|
|
(:import [goog History]
|
|
|
|
[goog.history Html5History]
|
|
|
|
[goog.history EventType]))
|
|
|
|
|
|
|
|
(def page (atom ""))
|
2014-01-27 21:30:42 +00:00
|
|
|
(def base-path (atom nil))
|
|
|
|
(def html5-history false)
|
2014-01-17 11:35:40 +00:00
|
|
|
|
|
|
|
(defn create-history []
|
|
|
|
(when reagent/is-client
|
|
|
|
(let [proto (-> js/window .-location .-protocol)]
|
|
|
|
(if (and (.isSupported Html5History)
|
|
|
|
(case proto "http:" true "https:" true false))
|
2014-01-27 21:30:42 +00:00
|
|
|
(do (set! html5-history true)
|
|
|
|
(doto (Html5History.)
|
|
|
|
(.setUseFragment false)))
|
2014-01-17 11:35:40 +00:00
|
|
|
(History.)))))
|
|
|
|
|
|
|
|
(defn setup-history []
|
|
|
|
(when-let [h (create-history)]
|
|
|
|
(events/listen h EventType/NAVIGATE
|
2014-01-27 21:30:42 +00:00
|
|
|
(fn [e] (reset! page (subs (.-token e)
|
|
|
|
(count @base-path)))))
|
2014-01-17 11:35:40 +00:00
|
|
|
(add-watch page ::history (fn [_ _ oldp newp]
|
2014-01-27 21:30:42 +00:00
|
|
|
(.setToken h (str @base-path newp))))
|
2014-01-17 11:35:40 +00:00
|
|
|
(.setEnabled h true)
|
|
|
|
h))
|
|
|
|
|
|
|
|
(def history (setup-history))
|
|
|
|
|
2014-01-27 21:30:42 +00:00
|
|
|
(defn set-start-page [p]
|
|
|
|
(when html5-history
|
|
|
|
;; Find base-path for html5 history
|
|
|
|
(let [loc (-> js/window .-location .-pathname)
|
|
|
|
split #".[^/]*"
|
|
|
|
loc-parts (re-seq split loc)
|
|
|
|
page-parts (re-seq split (case p "" "." p))
|
|
|
|
base (str (apply str
|
|
|
|
(drop-last (count page-parts) loc-parts))
|
|
|
|
"/")]
|
|
|
|
(reset! base-path (string/replace base #"^/" ""))))
|
|
|
|
(reset! page p))
|
|
|
|
|
2014-01-21 10:50:08 +00:00
|
|
|
(def title-atom (atom ""))
|
2014-01-17 11:35:40 +00:00
|
|
|
|
2014-01-21 10:50:08 +00:00
|
|
|
(def page-map (atom nil))
|
|
|
|
|
|
|
|
(def reverse-page-map (atom nil))
|
|
|
|
|
|
|
|
(add-watch page-map ::page-map-watch
|
|
|
|
(fn [_ _ _ new-map]
|
|
|
|
(reset! reverse-page-map
|
|
|
|
(into {} (for [[k v] new-map]
|
|
|
|
[v k])))))
|
|
|
|
|
|
|
|
(defn prefix [href]
|
|
|
|
(let [depth (-> #"/" (re-seq @page) count)]
|
|
|
|
(str (->> "../" (repeat depth) (apply str)) href)))
|
|
|
|
|
|
|
|
(defn link [props children]
|
|
|
|
(let [rpm @reverse-page-map
|
|
|
|
href (-> props :href rpm)]
|
|
|
|
(assert (string? href))
|
|
|
|
(apply vector
|
|
|
|
:a (assoc props
|
|
|
|
:href (prefix href)
|
|
|
|
:on-click (if history
|
|
|
|
(fn [e]
|
|
|
|
(.preventDefault e)
|
|
|
|
(reset! page href))
|
|
|
|
identity))
|
|
|
|
children)))
|
|
|
|
|
|
|
|
(defn title [props children]
|
|
|
|
(let [name (first children)]
|
|
|
|
(if reagent/is-client
|
|
|
|
(let [title (aget (.getElementsByTagName js/document "title") 0)]
|
|
|
|
(set! (.-innerHTML title) name)))
|
|
|
|
(reset! title-atom name)
|
|
|
|
[:div]))
|