mirror of
https://github.com/metosin/reitit.git
synced 2026-02-16 07:55:19 +00:00
Refactor ignore-anchor-click check to predicate function
This commit is contained in:
parent
5ffb9fc59f
commit
51c5aad492
2 changed files with 44 additions and 38 deletions
|
|
@ -31,8 +31,10 @@ event handling:
|
|||
(rfe/start!
|
||||
router
|
||||
{:use-fragment false
|
||||
:ignore-anchor-click (fn [e el]
|
||||
(not= "false" (gobj/get (.-dataset el) "reititHandleClick")))})
|
||||
:ignore-anchor-click? (fn [router e el uri]
|
||||
;; Add additional check on top of the default checks
|
||||
(and (rfh/ignore-anchor-click? router e el uri)
|
||||
(not= "false" (gobj/get (.-dataset el) "reititHandleClick"))))})
|
||||
|
||||
;; Use data-reitit-handle-click to disable Reitit anchor handling
|
||||
[:a
|
||||
|
|
|
|||
|
|
@ -67,6 +67,29 @@
|
|||
(first (.composedPath original-event))
|
||||
(.-target event))))
|
||||
|
||||
(defn ignore-anchor-click?
|
||||
"Precicate to check if the anchor click event default action
|
||||
should be ignored. This logic will ignore the event
|
||||
if anchor href matches the route tree, and in this case
|
||||
the page location is updated using History API."
|
||||
[router e el uri]
|
||||
(let [current-domain (if (exists? js/location)
|
||||
(.getDomain (.parse Uri js/location)))]
|
||||
(and (or (and (not (.hasScheme uri)) (not (.hasDomain uri)))
|
||||
(= current-domain (.getDomain uri)))
|
||||
(not (.-altKey e))
|
||||
(not (.-ctrlKey e))
|
||||
(not (.-metaKey e))
|
||||
(not (.-shiftKey e))
|
||||
(or (not (.hasAttribute el "target"))
|
||||
(contains? #{"" "_self"} (.getAttribute el "target")))
|
||||
;; Left button
|
||||
(= 0 (.-button e))
|
||||
;; isContentEditable property is inherited from parents,
|
||||
;; so if the anchor is inside contenteditable div, the property will be true.
|
||||
(not (.-isContentEditable el))
|
||||
(reitit/match-by-path router (.getPath uri)))))
|
||||
|
||||
(defrecord Html5History [on-navigate router listen-key click-listen-key]
|
||||
History
|
||||
(-init [this]
|
||||
|
|
@ -74,42 +97,22 @@
|
|||
(fn [e]
|
||||
(-on-navigate this (-get-path this)))
|
||||
|
||||
current-domain
|
||||
(if (exists? js/location)
|
||||
(.getDomain (.parse Uri js/location)))
|
||||
|
||||
ignore-anchor-click-fn (or (:ignore-anchor-click this)
|
||||
(constantly true))
|
||||
ignore-anchor-click-predicate (or (:ignore-anchor-click? this)
|
||||
ignore-anchor-click?)
|
||||
|
||||
;; Prevent document load when clicking a elements, if the href points to URL that is part
|
||||
;; of the routing tree."
|
||||
ignore-anchor-click
|
||||
(fn ignore-anchor-click
|
||||
[e]
|
||||
;; Returns the next matching anchestor of event target
|
||||
(when-let [el (closest-by-tag (event-target e) "a")]
|
||||
(let [uri (.parse Uri (.-href el))]
|
||||
(when (and (or (and (not (.hasScheme uri)) (not (.hasDomain uri)))
|
||||
(= current-domain (.getDomain uri)))
|
||||
(not (.-altKey e))
|
||||
(not (.-ctrlKey e))
|
||||
(not (.-metaKey e))
|
||||
(not (.-shiftKey e))
|
||||
(or (not (.hasAttribute el "target"))
|
||||
(contains? #{"" "_self"} (.getAttribute el "target")))
|
||||
;; Left button
|
||||
(= 0 (.-button e))
|
||||
;; isContentEditable property is inherited from parents,
|
||||
;; so if the anchor is inside contenteditable div, the property will be true.
|
||||
(not (.-isContentEditable el))
|
||||
(ignore-anchor-click-fn e el)
|
||||
(reitit/match-by-path router (.getPath uri)))
|
||||
(.preventDefault e)
|
||||
(let [path (str (.getPath uri)
|
||||
(if (seq (.getQuery uri))
|
||||
(str "?" (.getQuery uri))))]
|
||||
(.pushState js/window.history nil "" path)
|
||||
(-on-navigate this path))))))]
|
||||
ignore-anchor-click (fn [e]
|
||||
;; Returns the next matching anchestor of event target
|
||||
(when-let [el (closest-by-tag (event-target e) "a")]
|
||||
(let [uri (.parse Uri (.-href el))]
|
||||
(when (ignore-anchor-click-predicate router e el uri)
|
||||
(.preventDefault e)
|
||||
(let [path (str (.getPath uri)
|
||||
(if (seq (.getQuery uri))
|
||||
(str "?" (.getQuery uri))))]
|
||||
(.pushState js/window.history nil "" path)
|
||||
(-on-navigate this path))))))]
|
||||
(-on-navigate this (-get-path this))
|
||||
(assoc this
|
||||
:listen-key (gevents/listen js/window goog.events.EventType.POPSTATE handler false)
|
||||
|
|
@ -141,9 +144,10 @@
|
|||
- :use-fragment (default true) If true, onhashchange and location hash are used to store current route.
|
||||
|
||||
Options (Html5History):
|
||||
- :ignore-anchor-click Function (event, anchor element) to check if Reitit
|
||||
should handle click events on the anchor element. By default
|
||||
hrefs matching the route tree are handled by Reitit."
|
||||
- :ignore-anchor-click? Function (router, event, anchor element, uri) which will be called to
|
||||
check if the anchor click event should be ignored.
|
||||
To extend built-in check, you can call `reitit.frontend.history/ignore-anchor-click?`
|
||||
function, which will ignore clicks if the href matches route tree."
|
||||
([router on-navigate]
|
||||
(start! router on-navigate nil))
|
||||
([router
|
||||
|
|
|
|||
Loading…
Reference in a new issue