瀏覽代碼

Merge branch 'master' into update-scroll-history-lazy

Evan Almloff 1 年之前
父節點
當前提交
f7eba62a5d

+ 7 - 1
packages/router-macro/src/lib.rs

@@ -485,7 +485,13 @@ impl RouteEnum {
                     let mut segments = route.split('/');
                     let mut segments = route.split('/');
                     // skip the first empty segment
                     // skip the first empty segment
                     if s.starts_with('/') {
                     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();
                     let mut errors = Vec::new();
 
 

+ 1 - 1
packages/router-macro/src/route_tree.rs

@@ -367,7 +367,7 @@ impl<'a> RouteTreeSegmentData<'a> {
                         let child_name = &child.ident;
                         let child_name = &child.ident;
 
 
                         quote! {
                         quote! {
-                            let mut trailing = String::new();
+                            let mut trailing = String::from("/");
                             for seg in segments.clone() {
                             for seg in segments.clone() {
                                 trailing += seg;
                                 trailing += seg;
                                 trailing += "/";
                                 trailing += "/";

+ 2 - 2
packages/router/src/contexts/router.rs

@@ -178,7 +178,7 @@ impl RouterContext {
         match target {
         match target {
             NavigationTarget::Internal(p) => {
             NavigationTarget::Internal(p) => {
                 let mut state = self.state_mut();
                 let mut state = self.state_mut();
-                state.history.push(Rc::new(p))
+                state.history.push(p)
             }
             }
             NavigationTarget::External(e) => return self.external(e),
             NavigationTarget::External(e) => return self.external(e),
         }
         }
@@ -195,7 +195,7 @@ impl RouterContext {
         {
         {
             let mut state = self.state_mut();
             let mut state = self.state_mut();
             match target {
             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),
                 NavigationTarget::External(e) => return self.external(e),
             }
             }
         }
         }

+ 4 - 0
packages/router/src/history/memory.rs

@@ -88,6 +88,10 @@ impl<R: Routable> HistoryProvider<R> for MemoryHistory<R> {
     }
     }
 
 
     fn push(&mut self, new: R) {
     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);
         let old = std::mem::replace(&mut self.current, new);
         self.history.push(old);
         self.history.push(old);
         self.future.clear();
         self.future.clear();

+ 13 - 0
packages/router/src/history/web.rs

@@ -1,6 +1,7 @@
 use std::sync::{Arc, Mutex};
 use std::sync::{Arc, Mutex};
 
 
 use gloo::{console::error, events::EventListener, render::AnimationFrame};
 use gloo::{console::error, events::EventListener, render::AnimationFrame};
+
 use wasm_bindgen::JsValue;
 use wasm_bindgen::JsValue;
 use web_sys::{window, History, ScrollRestoration, Window};
 use web_sys::{window, History, ScrollRestoration, Window};
 
 
@@ -265,11 +266,18 @@ where
     }
     }
 
 
     fn push(&mut self, state: R) {
     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 w = window().expect("access to `window`");
         let w = window().expect("access to `window`");
         let h = w.history().expect("`window` has access to `history`");
         let h = w.history().expect("`window` has access to `history`");
 
 
         // update the scroll position before pushing the new state
         // update the scroll position before pushing the new state
         update_scroll::<R>(&w, &h);
         update_scroll::<R>(&w, &h);
+
         let path = self.full_path(&state);
         let path = self.full_path(&state);
 
 
         let state = self.create_state(state);
         let state = self.create_state(state);
@@ -336,6 +344,11 @@ where
     }
     }
 
 
     fn push(&mut self, state: R) {
     fn push(&mut self, state: R) {
+        if state.to_string() == self.current_route().to_string() {
+            // don't push the same state twice
+            return;
+        }
+
         let w = window().expect("access to `window`");
         let w = window().expect("access to `window`");
         let h = w.history().expect("`window` has access to `history`");
         let h = w.history().expect("`window` has access to `history`");