mirror of
https://github.com/metosin/reitit.git
synced 2025-12-18 17:01:11 +00:00
Merge pull request #601 from metosin/feature/update-query
Fix #600: Add frontend function to update query-params for current path
This commit is contained in:
commit
2a3e382df1
7 changed files with 233 additions and 35 deletions
|
|
@ -2,8 +2,16 @@
|
||||||
|
|
||||||
Reitit includes two browser history integrations.
|
Reitit includes two browser history integrations.
|
||||||
|
|
||||||
Functions follow HTML5 History API: `push-state` to change route, `replace-state`
|
Main functions are `navigate` and `set-query`. Navigate is used to navigate
|
||||||
to change route without leaving previous entry in browser history.
|
to named routes, and the options parameter can be used to control all
|
||||||
|
parameters and if `pushState` or `replaceState` should be used to control
|
||||||
|
browser history stack. The `set-query` function can be used to change
|
||||||
|
or modify query parameters for the current route, it takes either map of
|
||||||
|
new query params or function from old params to the new params.
|
||||||
|
|
||||||
|
There are also secondary functions following HTML5 History API:
|
||||||
|
`push-state` to navigate to new route adding entry to the history and
|
||||||
|
`replace-state` to change route without leaving previous entry in browser history.
|
||||||
|
|
||||||
## Fragment router
|
## Fragment router
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,17 @@
|
||||||
[:ul
|
[:ul
|
||||||
[:li [:a {:href (rfe/href ::item {:id 1})} "Item 1"]]
|
[:li [:a {:href (rfe/href ::item {:id 1})} "Item 1"]]
|
||||||
[:li [:a {:href (rfe/href ::item {:id 2} {:foo "bar"})} "Item 2"]]]
|
[:li [:a {:href (rfe/href ::item {:id 2} {:foo "bar"})} "Item 2"]]]
|
||||||
(if id
|
(when id
|
||||||
[:h2 "Selected item " id])
|
[:h2 "Selected item " id])
|
||||||
(if (:foo query)
|
[:p "Query params: " [:pre (pr-str query)]]
|
||||||
[:p "Optional foo query param: " (:foo query)])]))
|
[:ul
|
||||||
|
[:li [:a {:on-click #(rfe/set-query {:a 1})} "set a=1"]]
|
||||||
|
[:li [:a {:on-click #(rfe/set-query {:a 2} {:replace true})} "set a=2 and replaceState"]]
|
||||||
|
[:li [:a {:on-click (fn [_] (rfe/set-query #(assoc % :foo "zzz")))} "add foo=zzz"]]]
|
||||||
|
[:button
|
||||||
|
{:on-click #(rfe/navigate ::item {:path-params {:id 3}
|
||||||
|
:query-params {:foo "aaa"}})}
|
||||||
|
"Navigate example, go to item 3"]]))
|
||||||
|
|
||||||
(defonce match (r/atom nil))
|
(defonce match (r/atom nil))
|
||||||
|
|
||||||
|
|
@ -31,9 +38,8 @@
|
||||||
[:ul
|
[:ul
|
||||||
[:li [:a {:href (rfe/href ::frontpage)} "Frontpage"]]
|
[:li [:a {:href (rfe/href ::frontpage)} "Frontpage"]]
|
||||||
[:li
|
[:li
|
||||||
[:a {:href (rfe/href ::item-list)} "Item list"]
|
[:a {:href (rfe/href ::item-list)} "Item list"]]]
|
||||||
]]
|
(when @match
|
||||||
(if @match
|
|
||||||
(let [view (:view (:data @match))]
|
(let [view (:view (:data @match))]
|
||||||
[view @match]))
|
[view @match]))
|
||||||
[:pre (with-out-str (fedn/pprint @match))]])
|
[:pre (with-out-str (fedn/pprint @match))]])
|
||||||
|
|
@ -63,7 +69,8 @@
|
||||||
["/:id"
|
["/:id"
|
||||||
{:name ::item
|
{:name ::item
|
||||||
:parameters {:path {:id s/Int}
|
:parameters {:path {:id s/Int}
|
||||||
:query {(s/optional-key :foo) s/Keyword}}
|
:query {(s/optional-key :a) s/Int
|
||||||
|
(s/optional-key :foo) s/Keyword}}
|
||||||
:controllers [{:parameters {:path [:id]}
|
:controllers [{:parameters {:path [:id]}
|
||||||
:start (fn [{:keys [path]}]
|
:start (fn [{:keys [path]}]
|
||||||
(js/console.log "start" "item controller" (:id path)))
|
(js/console.log "start" "item controller" (:id path)))
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,41 @@
|
||||||
(ns reitit.frontend
|
(ns reitit.frontend
|
||||||
(:require [clojure.set :as set]
|
(:require [clojure.set :as set]
|
||||||
[reitit.coercion :as coercion]
|
[reitit.coercion :as coercion]
|
||||||
[reitit.core :as r])
|
[reitit.core :as r]
|
||||||
(:import goog.Uri
|
goog.Uri
|
||||||
goog.Uri.QueryData))
|
goog.Uri.QueryData))
|
||||||
|
|
||||||
(defn- query-param [^QueryData q k]
|
(defn- query-param [^goog.uri.QueryData q k]
|
||||||
(let [vs (.getValues q k)]
|
(let [vs (.getValues q k)]
|
||||||
(if (< (alength vs) 2)
|
(if (< (alength vs) 2)
|
||||||
(aget vs 0)
|
(aget vs 0)
|
||||||
(vec vs))))
|
(vec vs))))
|
||||||
|
|
||||||
(defn query-params
|
(defn query-params
|
||||||
"Given goog.Uri, read query parameters into Clojure map."
|
"Given goog.Uri, read query parameters into a Clojure map."
|
||||||
[^Uri uri]
|
[^goog.Uri uri]
|
||||||
(let [q (.getQueryData uri)]
|
(let [q (.getQueryData uri)]
|
||||||
(->> q
|
(->> q
|
||||||
(.getKeys)
|
(.getKeys)
|
||||||
(map (juxt keyword #(query-param q %)))
|
(map (juxt keyword #(query-param q %)))
|
||||||
(into {}))))
|
(into {}))))
|
||||||
|
|
||||||
|
(defn set-query-params
|
||||||
|
"Given Reitit-frontend path, update the query params
|
||||||
|
with given function and arguments.
|
||||||
|
|
||||||
|
Note: coercion is not applied to the query params"
|
||||||
|
[path new-query-or-update-fn]
|
||||||
|
(let [^goog.Uri uri (goog.Uri/parse path)
|
||||||
|
new-query (if (fn? new-query-or-update-fn)
|
||||||
|
(new-query-or-update-fn (query-params uri))
|
||||||
|
new-query-or-update-fn)]
|
||||||
|
;; NOTE: Differences to reitit.impl/query-string?
|
||||||
|
;; reitit fn adds "=" even if value is empty string
|
||||||
|
;; reitit encodes " " as "+" while browser and goog.Uri encode as "%20"
|
||||||
|
(.setQueryData uri (goog.Uri.QueryData/createFromMap (clj->js new-query)))
|
||||||
|
(.toString uri)))
|
||||||
|
|
||||||
(defn match-by-path
|
(defn match-by-path
|
||||||
"Given routing tree and current path, return match with possibly
|
"Given routing tree and current path, return match with possibly
|
||||||
coerced parameters. Return nil if no match found.
|
coerced parameters. Return nil if no match found.
|
||||||
|
|
@ -27,7 +43,7 @@
|
||||||
:on-coercion-error - a sideeffecting fn of `match exception -> nil`"
|
:on-coercion-error - a sideeffecting fn of `match exception -> nil`"
|
||||||
([router path] (match-by-path router path nil))
|
([router path] (match-by-path router path nil))
|
||||||
([router path {:keys [on-coercion-error]}]
|
([router path {:keys [on-coercion-error]}]
|
||||||
(let [uri (.parse Uri path)
|
(let [uri (.parse goog.Uri path)
|
||||||
coerce! (if on-coercion-error
|
coerce! (if on-coercion-error
|
||||||
(fn [match]
|
(fn [match]
|
||||||
(try (coercion/coerce! match)
|
(try (coercion/coerce! match)
|
||||||
|
|
|
||||||
|
|
@ -101,3 +101,44 @@
|
||||||
(rfh/replace-state @history name path-params nil))
|
(rfh/replace-state @history name path-params nil))
|
||||||
([name path-params query-params]
|
([name path-params query-params]
|
||||||
(rfh/replace-state @history name path-params query-params)))
|
(rfh/replace-state @history name path-params query-params)))
|
||||||
|
|
||||||
|
;; This duplicates previous two, but the map parameter will be easier way to
|
||||||
|
;; extend the functions, e.g. to work with fragment string. Toggling push vs
|
||||||
|
;; replace can be also simpler with a flag.
|
||||||
|
;; Navigate and set-query are also similer to react-router API.
|
||||||
|
(defn
|
||||||
|
^{:see-also ["reitit.frontend.history/navigate"]}
|
||||||
|
navigate
|
||||||
|
"Updates the browser location and either pushes new entry to the history stack
|
||||||
|
or replaces the latest entry in the the history stack (controlled by
|
||||||
|
`replace` option) using URL built from a route defined by name given
|
||||||
|
parameters.
|
||||||
|
|
||||||
|
Will also trigger on-navigate callback on Reitit frontend History handler.
|
||||||
|
|
||||||
|
Note: currently collections in query-parameters are encoded as field-value
|
||||||
|
pairs separated by &, i.e. \"?a=1&a=2\", if you want to encode them
|
||||||
|
differently, convert the collections to strings first.
|
||||||
|
|
||||||
|
See also:
|
||||||
|
https://developer.mozilla.org/en-US/docs/Web/API/History/pushState
|
||||||
|
https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState"
|
||||||
|
([name]
|
||||||
|
(rfh/navigate @history name))
|
||||||
|
([name {:keys [path-params query-params replace] :as opts}]
|
||||||
|
(rfh/navigate @history name opts)))
|
||||||
|
|
||||||
|
(defn
|
||||||
|
^{:see-also ["reitit.frontend.history/set-query"]}
|
||||||
|
set-query
|
||||||
|
"Update query parameters for the current route.
|
||||||
|
|
||||||
|
New query params can be given as a map, or a function taking
|
||||||
|
the old params and returning the new modified params.
|
||||||
|
|
||||||
|
Note: The query parameter values aren't coereced, so the
|
||||||
|
update fn will see string values for all query params."
|
||||||
|
([new-query-or-update-fn]
|
||||||
|
(rfh/set-query @history new-query-or-update-fn))
|
||||||
|
([new-query-or-update-fn {:keys [replace] :as opts}]
|
||||||
|
(rfh/set-query @history new-query-or-update-fn opts)))
|
||||||
|
|
|
||||||
|
|
@ -3,15 +3,15 @@
|
||||||
events."
|
events."
|
||||||
(:require [goog.events :as gevents]
|
(:require [goog.events :as gevents]
|
||||||
[reitit.core :as reitit]
|
[reitit.core :as reitit]
|
||||||
[reitit.frontend :as rf])
|
[reitit.frontend :as rf]
|
||||||
(:import goog.Uri))
|
goog.Uri))
|
||||||
|
|
||||||
(defprotocol History
|
(defprotocol History
|
||||||
(-init [this] "Create event listeners")
|
(-init [this] "Create event listeners")
|
||||||
(-stop [this] "Remove event listeners")
|
(-stop [this] "Remove event listeners")
|
||||||
(-on-navigate [this path])
|
(-on-navigate [this path] "Find a match for current routing path and call on-navigate callback")
|
||||||
(-get-path [this])
|
(-get-path [this] "Get the current routing path")
|
||||||
(-href [this path]))
|
(-href [this path] "Converts given routing path to browser location"))
|
||||||
|
|
||||||
;; This version listens for both pop-state and hash-change for
|
;; This version listens for both pop-state and hash-change for
|
||||||
;; compatibility for old browsers not supporting History API.
|
;; compatibility for old browsers not supporting History API.
|
||||||
|
|
@ -78,7 +78,7 @@
|
||||||
the page location is updated using History API."
|
the page location is updated using History API."
|
||||||
[router e el uri]
|
[router e el uri]
|
||||||
(let [current-domain (if (exists? js/location)
|
(let [current-domain (if (exists? js/location)
|
||||||
(.getDomain (.parse Uri js/location)))]
|
(.getDomain (.parse goog.Uri js/location)))]
|
||||||
(and (or (and (not (.hasScheme uri)) (not (.hasDomain uri)))
|
(and (or (and (not (.hasScheme uri)) (not (.hasDomain uri)))
|
||||||
(= current-domain (.getDomain uri)))
|
(= current-domain (.getDomain uri)))
|
||||||
(not (.-altKey e))
|
(not (.-altKey e))
|
||||||
|
|
@ -109,7 +109,7 @@
|
||||||
ignore-anchor-click (fn [e]
|
ignore-anchor-click (fn [e]
|
||||||
;; Returns the next matching ancestor of event target
|
;; Returns the next matching ancestor of event target
|
||||||
(when-let [el (closest-by-tag (event-target e) "a")]
|
(when-let [el (closest-by-tag (event-target e) "a")]
|
||||||
(let [uri (.parse Uri (.-href el))]
|
(let [uri (.parse goog.Uri (.-href el))]
|
||||||
(when (ignore-anchor-click-predicate router e el uri)
|
(when (ignore-anchor-click-predicate router e el uri)
|
||||||
(.preventDefault e)
|
(.preventDefault e)
|
||||||
(let [path (str (.getPath uri)
|
(let [path (str (.getPath uri)
|
||||||
|
|
@ -177,7 +177,9 @@
|
||||||
(if history
|
(if history
|
||||||
(-stop history)))
|
(-stop history)))
|
||||||
|
|
||||||
(defn href
|
(defn
|
||||||
|
^{:see-also ["reitit.core/match->path"]}
|
||||||
|
href
|
||||||
"Generate a URL for a route defined by name, with given path-params and query-params.
|
"Generate a URL for a route defined by name, with given path-params and query-params.
|
||||||
|
|
||||||
The URL is formatted using Reitit frontend history handler, so using it with
|
The URL is formatted using Reitit frontend history handler, so using it with
|
||||||
|
|
@ -219,7 +221,9 @@
|
||||||
(.pushState js/window.history nil "" (-href history path))
|
(.pushState js/window.history nil "" (-href history path))
|
||||||
(-on-navigate history path))))
|
(-on-navigate history path))))
|
||||||
|
|
||||||
(defn replace-state
|
(defn
|
||||||
|
^{:see-also ["reitit.core/match->path"]}
|
||||||
|
replace-state
|
||||||
"Updates the browser location and replaces latest entry in the history stack
|
"Updates the browser location and replaces latest entry in the history stack
|
||||||
using URL built from a route defined by name, with given path-params and
|
using URL built from a route defined by name, with given path-params and
|
||||||
query-params.
|
query-params.
|
||||||
|
|
@ -241,3 +245,50 @@
|
||||||
path (reitit/match->path match query-params)]
|
path (reitit/match->path match query-params)]
|
||||||
(.replaceState js/window.history nil "" (-href history path))
|
(.replaceState js/window.history nil "" (-href history path))
|
||||||
(-on-navigate history path))))
|
(-on-navigate history path))))
|
||||||
|
|
||||||
|
(defn
|
||||||
|
^{:see-also ["reitit.core/match->path"]}
|
||||||
|
navigate
|
||||||
|
"Updates the browser location and either pushes new entry to the history stack
|
||||||
|
or replaces the latest entry in the the history stack (controlled by
|
||||||
|
`replace` option) using URL built from a route defined by name given
|
||||||
|
parameters.
|
||||||
|
|
||||||
|
Will also trigger on-navigate callback on Reitit frontend History handler.
|
||||||
|
|
||||||
|
Note: currently collections in query-parameters are encoded as field-value
|
||||||
|
pairs separated by &, i.e. \"?a=1&a=2\", if you want to encode them
|
||||||
|
differently, convert the collections to strings first.
|
||||||
|
|
||||||
|
See also:
|
||||||
|
https://developer.mozilla.org/en-US/docs/Web/API/History/pushState
|
||||||
|
https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState"
|
||||||
|
([history name]
|
||||||
|
(navigate history name nil))
|
||||||
|
([history name {:keys [path-params query-params replace] :as opts}]
|
||||||
|
(let [match (rf/match-by-name! (:router history) name path-params)
|
||||||
|
path (reitit/match->path match query-params)]
|
||||||
|
(if replace
|
||||||
|
(.replaceState js/window.history nil "" (-href history path))
|
||||||
|
(.pushState js/window.history nil "" (-href history path)))
|
||||||
|
(-on-navigate history path))))
|
||||||
|
|
||||||
|
(defn
|
||||||
|
^{:see-also ["reitit.frontend/set-query-params"]}
|
||||||
|
set-query
|
||||||
|
"Update query parameters for the current route.
|
||||||
|
|
||||||
|
New query params can be given as a map, or a function taking
|
||||||
|
the old params and returning the new modified params.
|
||||||
|
|
||||||
|
Note: The query parameter values aren't coereced, so the
|
||||||
|
update fn will see string values for all query params."
|
||||||
|
([history new-query-or-update-fn]
|
||||||
|
(set-query history new-query-or-update-fn nil))
|
||||||
|
([history new-query-or-update-fn {:keys [replace] :as opts}]
|
||||||
|
(let [current-path (-get-path history)
|
||||||
|
new-path (rf/set-query-params current-path new-query-or-update-fn)]
|
||||||
|
(if replace
|
||||||
|
(.replaceState js/window.history nil "" (-href history new-path))
|
||||||
|
(.pushState js/window.history nil "" (-href history new-path)))
|
||||||
|
(-on-navigate history new-path))))
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,21 @@
|
||||||
[schema.core :as s]
|
[schema.core :as s]
|
||||||
[reitit.coercion.schema :as rcs]
|
[reitit.coercion.schema :as rcs]
|
||||||
[reitit.coercion.malli :as rcm]
|
[reitit.coercion.malli :as rcm]
|
||||||
[reitit.frontend.test-utils :refer [capture-console]]))
|
[reitit.frontend.test-utils :refer [capture-console]]
|
||||||
|
[reitit.impl :as impl]))
|
||||||
|
|
||||||
|
(deftest query-params-test
|
||||||
|
(is (= {:foo "1"}
|
||||||
|
(rf/query-params (.parse goog.Uri "?foo=1"))))
|
||||||
|
|
||||||
|
(is (= {:foo "1" :bar "aaa"}
|
||||||
|
(rf/query-params (.parse goog.Uri "?foo=1&bar=aaa"))))
|
||||||
|
|
||||||
|
(is (= {:foo ""}
|
||||||
|
(rf/query-params (.parse goog.Uri "?foo="))))
|
||||||
|
|
||||||
|
(is (= {:foo ""}
|
||||||
|
(rf/query-params (.parse goog.Uri "?foo")))))
|
||||||
|
|
||||||
(defn m [x]
|
(defn m [x]
|
||||||
(assoc x :data nil :result nil))
|
(assoc x :data nil :result nil))
|
||||||
|
|
@ -227,3 +241,44 @@
|
||||||
:token_type "bearer"
|
:token_type "bearer"
|
||||||
:expires_in 3600}}})
|
:expires_in 3600}}})
|
||||||
(m (rf/match-by-path router "/5?mode=foo#access_token=foo&refresh_token=bar&provider_token=baz&token_type=bearer&expires_in=3600"))))))))
|
(m (rf/match-by-path router "/5?mode=foo#access_token=foo&refresh_token=bar&provider_token=baz&token_type=bearer&expires_in=3600"))))))))
|
||||||
|
|
||||||
|
(deftest set-query-params-test
|
||||||
|
(is (= "foo?bar=1"
|
||||||
|
(rf/set-query-params "foo" {:bar 1})
|
||||||
|
(rf/set-query-params "foo" #(assoc % :bar 1))
|
||||||
|
;; Also compare to reitit.impl version which is used by match->path (and history fns)
|
||||||
|
(str "foo?" (impl/query-string {:bar 1}))))
|
||||||
|
|
||||||
|
(testing "Encoding"
|
||||||
|
(is (= "foo?bar=foo%20bar"
|
||||||
|
(rf/set-query-params "foo" {:bar "foo bar"})
|
||||||
|
(rf/set-query-params "foo" #(assoc % :bar "foo bar"))
|
||||||
|
;; FIXME: Reitit.impl encodes space as "+"
|
||||||
|
; (str "foo?" (impl/query-string {:bar "foo bar"}))
|
||||||
|
)))
|
||||||
|
|
||||||
|
(testing "Keep fragment"
|
||||||
|
(is (= "foo?bar=1&zzz=2#aaa"
|
||||||
|
(rf/set-query-params "foo?bar=1#aaa" #(assoc % :zzz 2)))))
|
||||||
|
|
||||||
|
(is (= "foo?asd=1&bar=1"
|
||||||
|
(rf/set-query-params "foo?asd=1" #(assoc % :bar 1))))
|
||||||
|
|
||||||
|
(is (= "foo?bar=1"
|
||||||
|
(rf/set-query-params "foo?asd=1&bar=1" #(dissoc % :asd))))
|
||||||
|
|
||||||
|
(is (= "foo?bar"
|
||||||
|
(rf/set-query-params "foo?asd=1&bar" #(dissoc % :asd))))
|
||||||
|
|
||||||
|
(is (= "foo?bar"
|
||||||
|
(rf/set-query-params "foo" #(assoc % :bar ""))
|
||||||
|
;; FIXME: Reitit.impl adds "=" for empty string values
|
||||||
|
; (str "foo?" (impl/query-string {:bar ""}))
|
||||||
|
))
|
||||||
|
|
||||||
|
(is (= "foo"
|
||||||
|
(rf/set-query-params "foo?asd=1" #(dissoc % :asd))))
|
||||||
|
|
||||||
|
(testing "Need to coerce current values manually"
|
||||||
|
(is (= "foo?foo=2"
|
||||||
|
(rf/set-query-params "foo?foo=1" (fn [q] (update q :foo #(inc (js/parseInt %)))))))))
|
||||||
|
|
|
||||||
|
|
@ -30,30 +30,50 @@
|
||||||
(is (= "/" url)
|
(is (= "/" url)
|
||||||
"start at root")
|
"start at root")
|
||||||
(rfe/push-state ::foo))
|
(rfe/push-state ::foo))
|
||||||
|
;; 0. /
|
||||||
|
;; 1. /foo
|
||||||
2 (do (is (= "/foo" url)
|
2 (do (is (= "/foo" url)
|
||||||
"push-state")
|
"push-state")
|
||||||
(.back js/window.history))
|
(.back js/window.history))
|
||||||
|
;; 0. /
|
||||||
3 (do (is (= "/" url)
|
3 (do (is (= "/" url)
|
||||||
"go back")
|
"go back")
|
||||||
(rfe/push-state ::bar {:id 1}))
|
(rfe/navigate ::bar {:path-params {:id 1}}))
|
||||||
|
;; 0. /
|
||||||
|
;; 1. /bar/1
|
||||||
4 (do (is (= "/bar/1" url)
|
4 (do (is (= "/bar/1" url)
|
||||||
"push-state 2")
|
"push-state 2")
|
||||||
(rfe/replace-state ::bar {:id 2}))
|
(rfe/replace-state ::bar {:id 2}))
|
||||||
|
;; 0. /
|
||||||
|
;; 1. /bar/2
|
||||||
5 (do (is (= "/bar/2" url)
|
5 (do (is (= "/bar/2" url)
|
||||||
"replace-state")
|
"replace-state")
|
||||||
(.back js/window.history))
|
(rfe/set-query {:a 1}))
|
||||||
6 (do (is (= "/" url)
|
;; 0. /
|
||||||
"go back after replace state")
|
;; 1. /bar/2
|
||||||
|
;; 2. /bar/2?a=1
|
||||||
|
6 (do (is (= "/bar/2?a=1" url)
|
||||||
|
"update-query with map")
|
||||||
|
(rfe/set-query #(assoc % :b "foo") {:replace true}))
|
||||||
|
;; 0. /
|
||||||
|
;; 1. /bar/2
|
||||||
|
;; 2. /bar/2?a=1&b=foo
|
||||||
|
7 (do (is (= "/bar/2?a=1&b=foo" url)
|
||||||
|
"update-query with fn")
|
||||||
|
(.go js/window.history -2))
|
||||||
|
;; 0. /
|
||||||
|
8 (do (is (= "/" url)
|
||||||
|
"go back two events")
|
||||||
|
|
||||||
;; Reset to ensure old event listeners aren't called
|
;; Reset to ensure old event listeners aren't called
|
||||||
(rfe/start! router
|
(rfe/start! router
|
||||||
(fn on-navigate [match history]
|
(fn on-navigate [match history]
|
||||||
(let [url (rfh/-get-path history)]
|
(let [url (rfh/-get-path history)]
|
||||||
(case (swap! n inc)
|
(case (swap! n inc)
|
||||||
7 (do (is (= "/" url)
|
9 (do (is (= "/" url)
|
||||||
"start at root")
|
"start at root")
|
||||||
(rfe/push-state ::foo))
|
(rfe/push-state ::foo))
|
||||||
8 (do (is (= "/foo" url)
|
10 (do (is (= "/foo" url)
|
||||||
"push-state")
|
"push-state")
|
||||||
(rfh/stop! @rfe/history)
|
(rfh/stop! @rfe/history)
|
||||||
(done))
|
(done))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue