From 98de423d9926ada35addb58a97e26b9acb838f91 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 1 Aug 2023 10:16:19 -0700 Subject: [PATCH 1/3] deduplicate route history --- packages/router/src/history/memory.rs | 4 ++++ packages/router/src/history/web.rs | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/packages/router/src/history/memory.rs b/packages/router/src/history/memory.rs index 07c1f4379..ba511bb97 100644 --- a/packages/router/src/history/memory.rs +++ b/packages/router/src/history/memory.rs @@ -88,6 +88,10 @@ impl HistoryProvider for MemoryHistory { } fn push(&mut self, new: R) { + // don't push the same route twice + if self.current.to_string() == new.to_string() { + return; + } let old = std::mem::replace(&mut self.current, new); self.history.push(old); self.future.clear(); diff --git a/packages/router/src/history/web.rs b/packages/router/src/history/web.rs index f7bd59dfa..e5589106f 100644 --- a/packages/router/src/history/web.rs +++ b/packages/router/src/history/web.rs @@ -1,6 +1,7 @@ use std::sync::{Arc, Mutex}; use gloo::{console::error, events::EventListener, render::AnimationFrame}; + use wasm_bindgen::JsValue; use web_sys::{window, History, ScrollRestoration, Window}; @@ -296,6 +297,11 @@ where } fn push(&mut self, state: R) { + use gloo_utils::format::JsValueSerdeExt; + if JsValue::from_serde(&state) != JsValue::from_serde(&self.current_route()) { + // don't push the same state twice + return; + } let path = self.full_path(&state); let state = self.create_state(state); @@ -362,6 +368,10 @@ where } fn push(&mut self, state: R) { + if state.to_string() == self.current_route().to_string() { + // don't push the same state twice + return; + } let path = self.full_path(&state); let state: [f64; 2] = self.create_state(state); From 4062e232d9accffd6de67d5ed0acccd1b30001c8 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Tue, 1 Aug 2023 10:21:16 -0700 Subject: [PATCH 2/3] fix navigator --- packages/router/src/contexts/router.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/router/src/contexts/router.rs b/packages/router/src/contexts/router.rs index e13d1cc20..5a9a3f0c4 100644 --- a/packages/router/src/contexts/router.rs +++ b/packages/router/src/contexts/router.rs @@ -178,7 +178,7 @@ impl RouterContext { match target { NavigationTarget::Internal(p) => { let mut state = self.state_mut(); - state.history.push(Rc::new(p)) + state.history.push(p) } NavigationTarget::External(e) => return self.external(e), } @@ -195,7 +195,7 @@ impl RouterContext { { let mut state = self.state_mut(); match target { - NavigationTarget::Internal(p) => state.history.replace(Rc::new(p)), + NavigationTarget::Internal(p) => state.history.replace(p), NavigationTarget::External(e) => return self.external(e), } } From 61ce3dd6b71723fb6d9f0f1bd28b321caf8ecf96 Mon Sep 17 00:00:00 2001 From: ealmloff Date: Tue, 1 Aug 2023 12:29:35 -0500 Subject: [PATCH 3/3] Reject all external routes when parsing a route (#1272) * reject all external routes when parsing a route * fix children routers --- packages/router-macro/src/lib.rs | 8 +++++++- packages/router-macro/src/route_tree.rs | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/router-macro/src/lib.rs b/packages/router-macro/src/lib.rs index 3b5ec85d7..c949cf2f4 100644 --- a/packages/router-macro/src/lib.rs +++ b/packages/router-macro/src/lib.rs @@ -485,7 +485,13 @@ impl RouteEnum { let mut segments = route.split('/'); // skip the first empty segment if s.starts_with('/') { - segments.next(); + let _ = segments.next(); + } + else { + // if this route does not start with a slash, it is not a valid route + return Err(dioxus_router::routable::RouteParseError { + attempted_routes: Vec::new(), + }); } let mut errors = Vec::new(); diff --git a/packages/router-macro/src/route_tree.rs b/packages/router-macro/src/route_tree.rs index d855d435a..399d20e5e 100644 --- a/packages/router-macro/src/route_tree.rs +++ b/packages/router-macro/src/route_tree.rs @@ -367,7 +367,7 @@ impl<'a> RouteTreeSegmentData<'a> { let child_name = &child.ident; quote! { - let mut trailing = String::new(); + let mut trailing = String::from("/"); for seg in segments.clone() { trailing += seg; trailing += "/";