mirror of
https://github.com/penpot/penpot.git
synced 2025-06-04 16:01:38 +02:00
feat(frontend): refactor router
This commit is contained in:
parent
076c29e004
commit
26cdebece4
23 changed files with 418 additions and 293 deletions
|
@ -27,7 +27,7 @@
|
|||
|
||||
(defn render-to-html
|
||||
[component]
|
||||
(.renderToStatciMarkup js/ReactDOMServer component))
|
||||
(.renderToStaticMarkup js/ReactDOMServer component))
|
||||
|
||||
(defn get-element-by-class
|
||||
([classname]
|
||||
|
|
29
frontend/src/uxbox/util/html_history.cljs
Normal file
29
frontend/src/uxbox/util/html_history.cljs
Normal file
|
@ -0,0 +1,29 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) 2015-2017 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.util.html-history
|
||||
"A singleton abstraction for the html5 fragment based history."
|
||||
(:require [goog.events :as e])
|
||||
(:import bide.impl.TokenTransformer
|
||||
goog.history.Html5History
|
||||
goog.history.EventType))
|
||||
|
||||
(defonce +instance+
|
||||
(doto (Html5History. nil (TokenTransformer.))
|
||||
(.setUseFragment true)
|
||||
(.setEnabled true)))
|
||||
|
||||
(defonce path (atom (.getToken +instance+)))
|
||||
|
||||
(e/listen +instance+ EventType.NAVIGATE #(reset! path (.-token %)))
|
||||
|
||||
(defn set-path!
|
||||
[path]
|
||||
(.setToken +instance+ path))
|
||||
|
||||
(defn replace-path!
|
||||
[path]
|
||||
(.replaceToken +instance+ path))
|
|
@ -2,65 +2,104 @@
|
|||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) 2015-2017 Andrey Antukh <niwi@niwi.nz>
|
||||
;; Copyright (c) 2015-2019 Andrey Antukh <niwi@niwi.nz>
|
||||
|
||||
(ns uxbox.util.router
|
||||
(:require [bide.core :as r]
|
||||
[beicon.core :as rx]
|
||||
[potok.core :as ptk]))
|
||||
(:require [reitit.core :as r]
|
||||
[cuerdas.core :as str]
|
||||
[potok.core :as ptk]
|
||||
[uxbox.util.html-history :as html-history])
|
||||
(:import goog.Uri
|
||||
goog.Uri.QueryData))
|
||||
|
||||
(defonce +router+ nil)
|
||||
|
||||
;; --- Update Location (Event)
|
||||
;; --- API
|
||||
|
||||
(deftype UpdateLocation [id params]
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(let [route (merge {:id id}
|
||||
(when params
|
||||
{:params params}))]
|
||||
(assoc state :route route))))
|
||||
(defn- parse-query-data
|
||||
[^QueryData qdata]
|
||||
(persistent!
|
||||
(reduce (fn [acc key]
|
||||
(let [values (.getValues qdata key)
|
||||
rkey (str/keyword key)]
|
||||
(cond
|
||||
(> (alength values) 1)
|
||||
(assoc! acc rkey (into [] values))
|
||||
|
||||
(defn update-location?
|
||||
[v]
|
||||
(instance? UpdateLocation v))
|
||||
(= (alength values) 1)
|
||||
(assoc! acc rkey (aget values 0))
|
||||
|
||||
(defn update-location
|
||||
[name params]
|
||||
(UpdateLocation. name params))
|
||||
:else
|
||||
acc)))
|
||||
(transient {})
|
||||
(.getKeys qdata))))
|
||||
|
||||
;; --- Navigate (Event)
|
||||
|
||||
(deftype Navigate [id params]
|
||||
ptk/EffectEvent
|
||||
(effect [_ state stream]
|
||||
(r/navigate! +router+ id params)))
|
||||
|
||||
(defn navigate
|
||||
([id] (navigate id nil))
|
||||
([id params]
|
||||
{:pre [(keyword? id)]}
|
||||
(Navigate. id params)))
|
||||
|
||||
;; --- Public Api
|
||||
(defn- resolve-url
|
||||
([router id] (resolve-url router id {} {}))
|
||||
([router id params] (resolve-url router id params {}))
|
||||
([router id params qparams]
|
||||
(when-let [match (r/match-by-name router id params)]
|
||||
(if (empty? qparams)
|
||||
(r/match->path match)
|
||||
(let [uri (.parse goog.Uri (r/match->path match))
|
||||
qdt (.createFromMap QueryData (clj->js qparams))]
|
||||
(.setQueryData uri qdt)
|
||||
(.toString uri))))))
|
||||
|
||||
(defn init
|
||||
[store routes {:keys [default] :or {default :auth/login}}]
|
||||
(let [opts {:on-navigate #(ptk/emit! store (update-location %1 %2))
|
||||
:default default}
|
||||
router (-> (r/router routes)
|
||||
(r/start! opts))]
|
||||
(set! +router+ router)
|
||||
router))
|
||||
[routes]
|
||||
(r/router routes))
|
||||
|
||||
(defn query-params
|
||||
"Given goog.Uri, read query parameters into Clojure map."
|
||||
[^goog.Uri uri]
|
||||
(let [q (.getQueryData uri)]
|
||||
(->> q
|
||||
(.getKeys)
|
||||
(map (juxt keyword #(.get q %)))
|
||||
(into {}))))
|
||||
|
||||
(defn navigate!
|
||||
([router id] (navigate! router id {} {}))
|
||||
([router id params] (navigate! router id params {}))
|
||||
([router id params qparams]
|
||||
(-> (resolve-url router id params qparams)
|
||||
(html-history/set-path!))))
|
||||
|
||||
(defn match
|
||||
"Given routing tree and current path, return match with possibly
|
||||
coerced parameters. Return nil if no match found."
|
||||
[router path]
|
||||
(let [uri (.parse Uri path)]
|
||||
(when-let [match (r/match-by-path router (.getPath uri))]
|
||||
(let [qparams (parse-query-data (.getQueryData uri))
|
||||
params {:path (:path-params match) :query qparams}]
|
||||
(assoc match
|
||||
:params params
|
||||
:query-params qparams)))))
|
||||
|
||||
(defn route-for
|
||||
"Given a location handler and optional parameter map, return the URI
|
||||
for such handler and parameters."
|
||||
([id]
|
||||
(if +router+
|
||||
(r/resolve +router+ id)
|
||||
""))
|
||||
([id] (route-for id {}))
|
||||
([id params]
|
||||
(if +router+
|
||||
(r/resolve +router+ id params)
|
||||
"")))
|
||||
(str (some-> +router+ (resolve-url id params)))))
|
||||
|
||||
;; --- Navigate (Event)
|
||||
|
||||
(deftype Navigate [id params qparams]
|
||||
ptk/EffectEvent
|
||||
(effect [_ state stream]
|
||||
(let [router (:router state)]
|
||||
(prn "Navigate:" id params qparams "| Match:" (resolve-url router id params qparams))
|
||||
(navigate! router id params qparams))))
|
||||
|
||||
(defn nav
|
||||
([id] (navigate id nil nil))
|
||||
([id params] (navigate id params nil))
|
||||
([id params qparams]
|
||||
{:pre [(keyword? id)]}
|
||||
(Navigate. id params qparams)))
|
||||
|
||||
(def navigate nav)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue