diff --git a/Guide.adoc b/Guide.adoc index 9f09b51..b1424ba 100644 --- a/Guide.adoc +++ b/Guide.adoc @@ -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 } without :leaf-id for cross-chart targets.")) ----- ==== Default: TransitBase64Codec diff --git a/src/main/com/fulcrologic/statecharts/integration/fulcro/routing.cljc b/src/main/com/fulcrologic/statecharts/integration/fulcro/routing.cljc index 3d27ebd..d8b4ecf 100644 --- a/src/main/com/fulcrologic/statecharts/integration/fulcro/routing.cljc +++ b/src/main/com/fulcrologic/statecharts/integration/fulcro/routing.cljc @@ -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)) @@ -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! diff --git a/src/main/com/fulcrologic/statecharts/integration/fulcro/routing/url_codec.cljc b/src/main/com/fulcrologic/statecharts/integration/fulcro/routing/url_codec.cljc index cda4344..202db85 100644 --- a/src/main/com/fulcrologic/statecharts/integration/fulcro/routing/url_codec.cljc +++ b/src/main/com/fulcrologic/statecharts/integration/fulcro/routing/url_codec.cljc @@ -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 :params }.")) + "Given a URL string and route-elements map, return {:leaf-id :params }, + or nil. May return {:params } 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) diff --git a/src/main/com/fulcrologic/statecharts/integration/fulcro/routing/url_codec_transit.cljc b/src/main/com/fulcrologic/statecharts/integration/fulcro/routing/url_codec_transit.cljc index fbb3cbd..f0027d4 100644 --- a/src/main/com/fulcrologic/statecharts/integration/fulcro/routing/url_codec_transit.cljc +++ b/src/main/com/fulcrologic/statecharts/integration/fulcro/routing/url_codec_transit.cljc @@ -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})))) diff --git a/src/test/com/fulcrologic/statecharts/integration/fulcro/routing/simulated_history_spec.cljc b/src/test/com/fulcrologic/statecharts/integration/fulcro/routing/simulated_history_spec.cljc index a752c05..b881f87 100644 --- a/src/test/com/fulcrologic/statecharts/integration/fulcro/routing/simulated_history_spec.cljc +++ b/src/test/com/fulcrologic/statecharts/integration/fulcro/routing/simulated_history_spec.cljc @@ -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"