Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1627,7 +1627,8 @@ URL encoding and decoding is handled by the `URLCodec` protocol defined in `rout
"Given a context map, return a URL path string (with query if needed).
Context keys: :segments, :params, :route-elements")
(decode-url [this href route-elements]
"Given a URL string and route-elements map, return {:leaf-id :params} or nil."))
"Given a URL string and route-elements map, return {:leaf-id :params}, or nil.
May return {:params <map>} without :leaf-id for cross-chart targets."))
-----

==== Default: TransitBase64Codec
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -986,8 +986,8 @@
[app elements-by-id provider codec]
(let [href (ruh/current-href provider)
decoded (ruc/decode-url codec href elements-by-id)]
(if decoded
(let [{:keys [leaf-id params]} decoded
(if-let [leaf-id (:leaf-id decoded)]
(let [{:keys [params]} decoded
route-params (when params
(reduce-kv (fn [acc _state-id state-params]
(merge acc state-params))
Expand All @@ -996,12 +996,16 @@
leaf-id)
;; Codec didn't match directly — try reachable targets via deep search
;; (needed for cross-chart :route/reachable targets not in this chart's elements)
(let [segments (ruh/current-url-path href)
leaf-name (peek segments)]
(let [segments (ruh/current-url-path href)
leaf-name (peek segments)
route-params (when-let [params (:params decoded)]
(reduce-kv (fn [acc _state-id state-params]
(merge acc state-params))
{} params))]
(when leaf-name
(when-let [{:keys [target-key child?]} (ruh/find-target-by-leaf-name-deep elements-by-id leaf-name)]
(when child?
(route-to! app target-key {})
(route-to! app target-key (or route-params {}))
target-key)))))))

(defn install-url-sync!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@
Context keys: :segments (vector of state IDs), :params (map keyed by state-id),
:route-elements (map of state-id -> element map).")
(decode-url [this href route-elements]
"Given a URL string and route-elements map, return {:leaf-id <state-id> :params <map>}."))
"Given a URL string and route-elements map, return {:leaf-id <state-id> :params <map>},
or nil. May return {:params <map>} without :leaf-id when params are present but the
leaf segment doesn't match a known route element (e.g. cross-chart targets)."))

;; ---------------------------------------------------------------------------
;; Path generation from active configuration (state -> URL)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
(= (url-codec/element-segment element) leaf-name))
id))
route-elements))]
(when leaf-id
(when (or leaf-id params)
{:leaf-id leaf-id
:params params}))))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,12 +396,12 @@
"decodes leaf matching by :route/segment"
(:leaf-id decoded) => :page-b)))

(component "decode returns nil for unrecognized URL"
(component "decode returns nil for unrecognized URL without params"
(let [codec (ruct/transit-base64-codec)
route-elements {:page-a {:route/target 'com.example/PageA}}
decoded (ruc/decode-url codec "/unknown/path" route-elements)]
(assertions
"returns nil when no route element matches the leaf segment"
"returns nil when no route element matches and no params present"
decoded => nil)))

(component "single segment route"
Expand Down