mirror of
https://github.com/metosin/reitit.git
synced 2025-12-18 17:01:11 +00:00
commit
f2f7d3a428
6 changed files with 72 additions and 50 deletions
|
|
@ -18,6 +18,11 @@ We use [Break Versioning][breakver]. The version numbers follow a `<major>.<mino
|
||||||
|
|
||||||
## 0.5.7 (2020-10-18)
|
## 0.5.7 (2020-10-18)
|
||||||
|
|
||||||
|
### `reitit-frontend`
|
||||||
|
|
||||||
|
- `reitit.frontend.easy/start!` now correctly removes old event listeners
|
||||||
|
when called repeatedly (e.g. with hot code reload workflow)
|
||||||
|
([#438](https://github.com/metosin/reitit/pull/438))
|
||||||
* updated deps:
|
* updated deps:
|
||||||
|
|
||||||
```clj
|
```clj
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@
|
||||||
{:builds
|
{:builds
|
||||||
[{:id "dev"
|
[{:id "dev"
|
||||||
:source-paths ["src/cljs"]
|
:source-paths ["src/cljs"]
|
||||||
:figwheel {:on-jsload "frontend-re-frame.core/mount-root"}
|
:figwheel true
|
||||||
:compiler {:main frontend-re-frame.core
|
:compiler {:main frontend-re-frame.core
|
||||||
:output-to "resources/public/js/compiled/app.js"
|
:output-to "resources/public/js/compiled/app.js"
|
||||||
:output-dir "resources/public/js/compiled/out"
|
:output-dir "resources/public/js/compiled/out"
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,9 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset='utf-8'>
|
<meta charset='utf-8'>
|
||||||
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<script src="js/compiled/app.js"></script>
|
<script src="js/compiled/app.js"></script>
|
||||||
<script>frontend_re_frame.core.init();</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -9,30 +9,27 @@
|
||||||
|
|
||||||
;;; Events ;;;
|
;;; Events ;;;
|
||||||
|
|
||||||
(re-frame/reg-event-db
|
(re-frame/reg-event-db ::initialize-db
|
||||||
::initialize-db
|
(fn [db _]
|
||||||
(fn [_ _]
|
(if db
|
||||||
{:current-route nil}))
|
db
|
||||||
|
{:current-route nil})))
|
||||||
|
|
||||||
(re-frame/reg-event-fx
|
(re-frame/reg-event-fx ::push-state
|
||||||
::navigate
|
(fn [db [_ & route]]
|
||||||
(fn [db [_ & route]]
|
{:push-state route}))
|
||||||
;; See `navigate` effect in routes.cljs
|
|
||||||
{::navigate! route}))
|
|
||||||
|
|
||||||
(re-frame/reg-event-db
|
(re-frame/reg-event-db ::navigated
|
||||||
::navigated
|
(fn [db [_ new-match]]
|
||||||
(fn [db [_ new-match]]
|
(let [old-match (:current-route db)
|
||||||
(let [old-match (:current-route db)
|
controllers (rfc/apply-controllers (:controllers old-match) new-match)]
|
||||||
controllers (rfc/apply-controllers (:controllers old-match) new-match)]
|
(assoc db :current-route (assoc new-match :controllers controllers)))))
|
||||||
(assoc db :current-route (assoc new-match :controllers controllers)))))
|
|
||||||
|
|
||||||
;;; Subscriptions ;;;
|
;;; Subscriptions ;;;
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub ::current-route
|
||||||
::current-route
|
(fn [db]
|
||||||
(fn [db]
|
(:current-route db)))
|
||||||
(:current-route db)))
|
|
||||||
|
|
||||||
;;; Views ;;;
|
;;; Views ;;;
|
||||||
|
|
||||||
|
|
@ -41,7 +38,7 @@
|
||||||
[:h1 "This is home page"]
|
[:h1 "This is home page"]
|
||||||
[:button
|
[:button
|
||||||
;; Dispatch navigate event that triggers a (side)effect.
|
;; Dispatch navigate event that triggers a (side)effect.
|
||||||
{:on-click #(re-frame/dispatch [::navigate ::sub-page2])}
|
{:on-click #(re-frame/dispatch [::push-state ::sub-page2])}
|
||||||
"Go to sub-page 2"]])
|
"Go to sub-page 2"]])
|
||||||
|
|
||||||
(defn sub-page1 []
|
(defn sub-page1 []
|
||||||
|
|
@ -55,10 +52,10 @@
|
||||||
;;; Effects ;;;
|
;;; Effects ;;;
|
||||||
|
|
||||||
;; Triggering navigation from events.
|
;; Triggering navigation from events.
|
||||||
(re-frame/reg-fx
|
|
||||||
::navigate!
|
(re-frame/reg-fx :push-state
|
||||||
(fn [route]
|
(fn [route]
|
||||||
(apply rfe/push-state route)))
|
(apply rfe/push-state route)))
|
||||||
|
|
||||||
;;; Routes ;;;
|
;;; Routes ;;;
|
||||||
|
|
||||||
|
|
@ -104,15 +101,15 @@
|
||||||
|
|
||||||
(def router
|
(def router
|
||||||
(rf/router
|
(rf/router
|
||||||
routes
|
routes
|
||||||
{:data {:coercion rss/coercion}}))
|
{:data {:coercion rss/coercion}}))
|
||||||
|
|
||||||
(defn init-routes! []
|
(defn init-routes! []
|
||||||
(js/console.log "initializing routes")
|
(js/console.log "initializing routes")
|
||||||
(rfe/start!
|
(rfe/start!
|
||||||
router
|
router
|
||||||
on-navigate
|
on-navigate
|
||||||
{:use-fragment true}))
|
{:use-fragment true}))
|
||||||
|
|
||||||
(defn nav [{:keys [router current-route]}]
|
(defn nav [{:keys [router current-route]}]
|
||||||
[:ul
|
[:ul
|
||||||
|
|
@ -141,13 +138,12 @@
|
||||||
(enable-console-print!)
|
(enable-console-print!)
|
||||||
(println "dev mode")))
|
(println "dev mode")))
|
||||||
|
|
||||||
(defn mount-root []
|
(defn init []
|
||||||
(re-frame/clear-subscription-cache!)
|
(re-frame/clear-subscription-cache!)
|
||||||
|
(re-frame/dispatch-sync [::initialize-db])
|
||||||
|
(dev-setup)
|
||||||
(init-routes!) ;; Reset routes on figwheel reload
|
(init-routes!) ;; Reset routes on figwheel reload
|
||||||
(reagent/render [router-component {:router router}]
|
(reagent/render [router-component {:router router}]
|
||||||
(.getElementById js/document "app")))
|
(.getElementById js/document "app")))
|
||||||
|
|
||||||
(defn ^:export init []
|
(init)
|
||||||
(re-frame/dispatch-sync [::initialize-db])
|
|
||||||
(dev-setup)
|
|
||||||
(mount-root))
|
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,14 @@
|
||||||
(let [path (-get-path this)]
|
(let [path (-get-path this)]
|
||||||
(when (or (= goog.events.EventType.POPSTATE (.-type e))
|
(when (or (= goog.events.EventType.POPSTATE (.-type e))
|
||||||
(not= @last-fragment path))
|
(not= @last-fragment path))
|
||||||
(-on-navigate this path))))]
|
(-on-navigate this path))))
|
||||||
|
;; rfe start! uses first on-navigate call to store the
|
||||||
|
;; instance so it has to see the instance with listeners.
|
||||||
|
this (assoc this
|
||||||
|
:popstate-listener (gevents/listen js/window goog.events.EventType.POPSTATE handler false)
|
||||||
|
:hashchange-listener (gevents/listen js/window goog.events.EventType.HASHCHANGE handler false))]
|
||||||
(-on-navigate this (-get-path this))
|
(-on-navigate this (-get-path this))
|
||||||
(assoc this
|
this))
|
||||||
:popstate-listener (gevents/listen js/window goog.events.EventType.POPSTATE handler false)
|
|
||||||
:hashchange-listener (gevents/listen js/window goog.events.EventType.HASHCHANGE handler false))))
|
|
||||||
(-stop [this]
|
(-stop [this]
|
||||||
(gevents/unlistenByKey popstate-listener)
|
(gevents/unlistenByKey popstate-listener)
|
||||||
(gevents/unlistenByKey hashchange-listener)
|
(gevents/unlistenByKey hashchange-listener)
|
||||||
|
|
@ -115,11 +118,12 @@
|
||||||
(when (.hasFragment uri)
|
(when (.hasFragment uri)
|
||||||
(str "#" (.getFragment uri))))]
|
(str "#" (.getFragment uri))))]
|
||||||
(.pushState js/window.history nil "" path)
|
(.pushState js/window.history nil "" path)
|
||||||
(-on-navigate this path))))))]
|
(-on-navigate this path))))))
|
||||||
|
this (assoc this
|
||||||
|
:listen-key (gevents/listen js/window goog.events.EventType.POPSTATE handler false)
|
||||||
|
:click-listen-key (gevents/listen js/document goog.events.EventType.CLICK ignore-anchor-click))]
|
||||||
(-on-navigate this (-get-path this))
|
(-on-navigate this (-get-path this))
|
||||||
(assoc this
|
this))
|
||||||
:listen-key (gevents/listen js/window goog.events.EventType.POPSTATE handler false)
|
|
||||||
:click-listen-key (gevents/listen js/document goog.events.EventType.CLICK ignore-anchor-click))))
|
|
||||||
(-on-navigate [this path]
|
(-on-navigate [this path]
|
||||||
(on-navigate (rf/match-by-path router path) this))
|
(on-navigate (rf/match-by-path router path) this))
|
||||||
(-stop [this]
|
(-stop [this]
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@
|
||||||
["foo" ::foo]
|
["foo" ::foo]
|
||||||
["bar/:id" ::bar]]))
|
["bar/:id" ::bar]]))
|
||||||
|
|
||||||
|
;; TODO: Only tests fragment history, also test HTML5?
|
||||||
|
|
||||||
(deftest easy-history-routing-test
|
(deftest easy-history-routing-test
|
||||||
(when browser
|
(when browser
|
||||||
(gevents/removeAll js/window goog.events.EventType.POPSTATE)
|
(gevents/removeAll js/window goog.events.EventType.POPSTATE)
|
||||||
|
|
@ -24,7 +26,8 @@
|
||||||
(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)
|
||||||
1 (do (is (= "/" url)
|
1 (do (is (some? (:popstate-listener history)))
|
||||||
|
(is (= "/" url)
|
||||||
"start at root")
|
"start at root")
|
||||||
(rfe/push-state ::foo))
|
(rfe/push-state ::foo))
|
||||||
2 (do (is (= "/foo" url)
|
2 (do (is (= "/foo" url)
|
||||||
|
|
@ -41,7 +44,24 @@
|
||||||
(.back js/window.history))
|
(.back js/window.history))
|
||||||
6 (do (is (= "/" url)
|
6 (do (is (= "/" url)
|
||||||
"go back after replace state")
|
"go back after replace state")
|
||||||
(rfh/stop! @rfe/history)
|
|
||||||
(done))
|
;; Reset to ensure old event listeners aren't called
|
||||||
(is false "extra event"))))
|
(rfe/start! router
|
||||||
|
(fn on-navigate [match history]
|
||||||
|
(let [url (rfh/-get-path history)]
|
||||||
|
(case (swap! n inc)
|
||||||
|
7 (do (is (= "/" url)
|
||||||
|
"start at root")
|
||||||
|
(rfe/push-state ::foo))
|
||||||
|
8 (do (is (= "/foo" url)
|
||||||
|
"push-state")
|
||||||
|
(rfh/stop! @rfe/history)
|
||||||
|
(done))
|
||||||
|
(do
|
||||||
|
(is false (str "extra event 2" {:n @n, :url url}))
|
||||||
|
(done)))))
|
||||||
|
{:use-fragment true}))
|
||||||
|
(do
|
||||||
|
(is false (str "extra event 1" {:n @n, :url url}))
|
||||||
|
(done)))))
|
||||||
{:use-fragment true})))))
|
{:use-fragment true})))))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue