From 1320c17793f6e98d44db0f0dfe377b82c21c2bfc Mon Sep 17 00:00:00 2001 From: Jedd Dryden <40693089+Jaffa-Cakes@users.noreply.github.com> Date: Mon, 27 Mar 2023 23:40:56 +1100 Subject: [PATCH 01/11] Escape for URL in `routable_derive` --- Cargo.lock | 7 +++++++ packages/yew-router-macro/src/routable_derive.rs | 2 +- packages/yew-router/Cargo.toml | 1 + packages/yew-router/src/lib.rs | 1 + 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 1ddcbdc72c0..64191e484a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2917,6 +2917,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "urlencoding" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" + [[package]] name = "utf-8" version = "0.7.6" @@ -3349,6 +3355,7 @@ dependencies = [ "serde", "serde_urlencoded", "tracing", + "urlencoding", "wasm-bindgen", "wasm-bindgen-test", "web-sys", diff --git a/packages/yew-router-macro/src/routable_derive.rs b/packages/yew-router-macro/src/routable_derive.rs index 76d8011f2ca..5a4aeb99d1f 100644 --- a/packages/yew-router-macro/src/routable_derive.rs +++ b/packages/yew-router-macro/src/routable_derive.rs @@ -176,7 +176,7 @@ impl Routable { } quote! { - Self::#ident { #(#fields),* } => ::std::format!(#right, #(#fields = #fields),*) + Self::#ident { #(#fields),* } => ::std::format!(#right, #(#fields = yew_router::encode_for_url(#fields)),*) } } Fields::Unnamed(_) => unreachable!(), // already checked diff --git a/packages/yew-router/Cargo.toml b/packages/yew-router/Cargo.toml index 4ee485b4085..63af24e9743 100644 --- a/packages/yew-router/Cargo.toml +++ b/packages/yew-router/Cargo.toml @@ -22,6 +22,7 @@ route-recognizer = "0.3" serde = "1" serde_urlencoded = "0.7.1" tracing = "0.1.36" +urlencoding = "2" [dependencies.web-sys] version = "0.3" diff --git a/packages/yew-router/src/lib.rs b/packages/yew-router/src/lib.rs index 1cf262e21d8..f7578842179 100644 --- a/packages/yew-router/src/lib.rs +++ b/packages/yew-router/src/lib.rs @@ -80,6 +80,7 @@ pub mod utils; pub use routable::{AnyRoute, Routable}; pub use router::{BrowserRouter, HashRouter, Router}; pub use switch::Switch; +pub use urlencoding::encode as encode_for_url; pub mod history { //! A module that provides universal session history and location information. From a1277faadd32cbf3dc6282da61cc818d8ee04326 Mon Sep 17 00:00:00 2001 From: Jedd Dryden <40693089+Jaffa-Cakes@users.noreply.github.com> Date: Tue, 28 Mar 2023 00:19:23 +1100 Subject: [PATCH 02/11] Fixed generic datatypes bug --- packages/yew-router-macro/src/routable_derive.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/yew-router-macro/src/routable_derive.rs b/packages/yew-router-macro/src/routable_derive.rs index 5a4aeb99d1f..b7d96922d1a 100644 --- a/packages/yew-router-macro/src/routable_derive.rs +++ b/packages/yew-router-macro/src/routable_derive.rs @@ -176,7 +176,7 @@ impl Routable { } quote! { - Self::#ident { #(#fields),* } => ::std::format!(#right, #(#fields = yew_router::encode_for_url(#fields)),*) + Self::#ident { #(#fields),* } => ::std::format!(#right, #(#fields = yew_router::encode_for_url(&format!("{}", #fields))),*) } } Fields::Unnamed(_) => unreachable!(), // already checked From 32f5fe06d08edcc7636c84a9dfae6ca9139453b0 Mon Sep 17 00:00:00 2001 From: Jedd Dryden <40693089+Jaffa-Cakes@users.noreply.github.com> Date: Tue, 28 Mar 2023 17:43:33 +1100 Subject: [PATCH 03/11] FQN --- packages/yew-router-macro/src/routable_derive.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/yew-router-macro/src/routable_derive.rs b/packages/yew-router-macro/src/routable_derive.rs index b7d96922d1a..14421401358 100644 --- a/packages/yew-router-macro/src/routable_derive.rs +++ b/packages/yew-router-macro/src/routable_derive.rs @@ -176,7 +176,7 @@ impl Routable { } quote! { - Self::#ident { #(#fields),* } => ::std::format!(#right, #(#fields = yew_router::encode_for_url(&format!("{}", #fields))),*) + Self::#ident { #(#fields),* } => ::std::format!(#right, #(#fields = ::yew_router::encode_for_url(&format!("{}", #fields))),*) } } Fields::Unnamed(_) => unreachable!(), // already checked From b03b36172be725012e15b5ce296ecaae9b2b7e77 Mon Sep 17 00:00:00 2001 From: Jedd Dryden <40693089+Jaffa-Cakes@users.noreply.github.com> Date: Tue, 28 Mar 2023 17:48:30 +1100 Subject: [PATCH 04/11] FQN Again --- packages/yew-router-macro/src/routable_derive.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/yew-router-macro/src/routable_derive.rs b/packages/yew-router-macro/src/routable_derive.rs index 14421401358..8f5a0951e01 100644 --- a/packages/yew-router-macro/src/routable_derive.rs +++ b/packages/yew-router-macro/src/routable_derive.rs @@ -176,7 +176,7 @@ impl Routable { } quote! { - Self::#ident { #(#fields),* } => ::std::format!(#right, #(#fields = ::yew_router::encode_for_url(&format!("{}", #fields))),*) + Self::#ident { #(#fields),* } => ::std::format!(#right, #(#fields = ::yew_router::encode_for_url(&::std::format!("{}", #fields))),*) } } Fields::Unnamed(_) => unreachable!(), // already checked From 07c0ccbba0425403a3fa41da26212cac92136f27 Mon Sep 17 00:00:00 2001 From: Muhammad Hamza Date: Thu, 1 Jun 2023 17:29:32 +0500 Subject: [PATCH 05/11] remove encode_for_url from public API --- packages/yew-router-macro/src/routable_derive.rs | 2 +- packages/yew-router/src/lib.rs | 1 - packages/yew-router/src/macro_helpers.rs | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/yew-router-macro/src/routable_derive.rs b/packages/yew-router-macro/src/routable_derive.rs index 9d354619964..9f55aadb856 100644 --- a/packages/yew-router-macro/src/routable_derive.rs +++ b/packages/yew-router-macro/src/routable_derive.rs @@ -176,7 +176,7 @@ impl Routable { } quote! { - Self::#ident { #(#fields),* } => ::std::format!(#right, #(#fields = ::yew_router::encode_for_url(&::std::format!("{}", #fields))),*) + Self::#ident { #(#fields),* } => ::std::format!(#right, #(#fields = ::yew_router::__macro::encode_for_url(&::std::format!("{}", #fields))),*) } } Fields::Unnamed(_) => unreachable!(), // already checked diff --git a/packages/yew-router/src/lib.rs b/packages/yew-router/src/lib.rs index f7578842179..1cf262e21d8 100644 --- a/packages/yew-router/src/lib.rs +++ b/packages/yew-router/src/lib.rs @@ -80,7 +80,6 @@ pub mod utils; pub use routable::{AnyRoute, Routable}; pub use router::{BrowserRouter, HashRouter, Router}; pub use switch::Switch; -pub use urlencoding::encode as encode_for_url; pub mod history { //! A module that provides universal session history and location information. diff --git a/packages/yew-router/src/macro_helpers.rs b/packages/yew-router/src/macro_helpers.rs index a8d06e69d66..106d7f67d55 100644 --- a/packages/yew-router/src/macro_helpers.rs +++ b/packages/yew-router/src/macro_helpers.rs @@ -1,5 +1,6 @@ use crate::utils::strip_slash_suffix; use crate::Routable; +pub use urlencoding::encode as encode_for_url; // re-export Router because the macro needs to access it pub type Router = route_recognizer::Router; From 31ddfa77628ec045060e0f5e77c666d382fe6451 Mon Sep 17 00:00:00 2001 From: Muhammad Hamza Date: Fri, 2 Jun 2023 22:55:58 +0500 Subject: [PATCH 06/11] fmt --- packages/yew-router/src/macro_helpers.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/yew-router/src/macro_helpers.rs b/packages/yew-router/src/macro_helpers.rs index 106d7f67d55..67d73acb4d7 100644 --- a/packages/yew-router/src/macro_helpers.rs +++ b/packages/yew-router/src/macro_helpers.rs @@ -1,6 +1,7 @@ +pub use urlencoding::encode as encode_for_url; + use crate::utils::strip_slash_suffix; use crate::Routable; -pub use urlencoding::encode as encode_for_url; // re-export Router because the macro needs to access it pub type Router = route_recognizer::Router; From 905cb91f2f6383ff0d623211b2f82e372b10676d Mon Sep 17 00:00:00 2001 From: Muhammad Hamza Date: Tue, 13 Jun 2023 21:35:27 +0500 Subject: [PATCH 07/11] url decode parameters --- packages/yew-router-macro/src/routable_derive.rs | 7 ++++++- packages/yew-router/src/macro_helpers.rs | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/yew-router-macro/src/routable_derive.rs b/packages/yew-router-macro/src/routable_derive.rs index 9f55aadb856..ae8597a81a2 100644 --- a/packages/yew-router-macro/src/routable_derive.rs +++ b/packages/yew-router-macro/src/routable_derive.rs @@ -132,7 +132,12 @@ impl Routable { //named fields have idents it.ident.as_ref().unwrap() }); - quote! { Self::#ident { #(#fields: params.get(stringify!(#fields))?.parse().ok()?,)* } } + quote! { Self::#ident { #(#fields: { + let param = params.get(stringify!(#fields))?; + let param = &*::yew_router::__macro::decode_for_url(param).ok()?; + let param = param.parse().ok()?; + param + },)* } } } Fields::Unnamed(_) => unreachable!(), // already checked }; diff --git a/packages/yew-router/src/macro_helpers.rs b/packages/yew-router/src/macro_helpers.rs index 67d73acb4d7..71b85b07126 100644 --- a/packages/yew-router/src/macro_helpers.rs +++ b/packages/yew-router/src/macro_helpers.rs @@ -1,4 +1,5 @@ pub use urlencoding::encode as encode_for_url; +pub use urlencoding::decode as decode_for_url; use crate::utils::strip_slash_suffix; use crate::Routable; From 3aaea764510ce789dff7ef01a3c8c8c08b4f8146 Mon Sep 17 00:00:00 2001 From: Muhammad Hamza Date: Tue, 13 Jun 2023 21:35:36 +0500 Subject: [PATCH 08/11] add test --- .../yew-router/tests/router_unit_tests.rs | 24 +++++++ .../yew-router/tests/url_encoded_routes.rs | 67 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 packages/yew-router/tests/url_encoded_routes.rs diff --git a/packages/yew-router/tests/router_unit_tests.rs b/packages/yew-router/tests/router_unit_tests.rs index 869060643eb..0f79db55db8 100644 --- a/packages/yew-router/tests/router_unit_tests.rs +++ b/packages/yew-router/tests/router_unit_tests.rs @@ -16,6 +16,7 @@ fn router_always_404() { NotFound, } + assert_eq!( Some(AppRoute::NotFound), AppRoute::recognize("/not/matched/route") @@ -48,3 +49,26 @@ fn router_trailing_slash() { AppRoute::recognize("/category/cooking-recipes/") ); } + +#[test] +fn router_url_encoding() { + #[derive(Routable, Debug, Clone, PartialEq)] + enum AppRoute { + #[at("/")] + Root, + #[at("/search/:query")] + Search { query: String }, + } + + assert_eq!( + yew_router::__macro::decode_for_url("/search/a%2Fb/").unwrap(), + "/search/a/b/" + ); + + assert_eq!( + Some(AppRoute::Search { + query: "a/b".to_string() + }), + AppRoute::recognize("/search/a%2Fb/") + ); +} diff --git a/packages/yew-router/tests/url_encoded_routes.rs b/packages/yew-router/tests/url_encoded_routes.rs new file mode 100644 index 00000000000..304c30ca3a1 --- /dev/null +++ b/packages/yew-router/tests/url_encoded_routes.rs @@ -0,0 +1,67 @@ +use std::time::Duration; +use yew::platform::time::sleep; +use yew_router::prelude::*; +use yew::prelude::*; + +mod utils; +use utils::*; +use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure}; +wasm_bindgen_test_configure!(run_in_browser); + + + +#[derive(Routable, Debug, Clone, PartialEq)] +enum AppRoute { + #[at("/")] + Root, + #[at("/search/:query")] + Search { query: String }, +} + +#[function_component] +fn Comp() -> Html { + let switch = move |routes: AppRoute| { + match routes { + AppRoute::Root => html! { + <> +

{ "Root" }

+ to={AppRoute::Search { query: "a/b".to_string() }}> + {"Click me"} + > + + }, + AppRoute::Search { query } => html! { +

{ query }

+ }, + } + }; + html! { + render={switch} /> + } +} + +#[function_component(Root)] +fn root() -> Html { + html! { + + + + } +} + + +#[test] +async fn url_encoded_roundtrip() { + yew::Renderer::::with_root(gloo::utils::document().get_element_by_id("output").unwrap()) + .render(); + sleep(Duration::ZERO).await; + click("a"); + sleep(Duration::ZERO).await; + let res = obtain_result_by_id("q"); + assert_eq!(res, "a/b"); + + assert_eq!( + gloo::utils::window().location().pathname().unwrap().to_string(), + "/search/a%2Fb" + ) +} \ No newline at end of file From ef727b31c69d5f9774b0b5a4ba808bc6de49ebab Mon Sep 17 00:00:00 2001 From: Muhammad Hamza Date: Tue, 13 Jun 2023 21:35:47 +0500 Subject: [PATCH 09/11] fmt --- .../yew-router-macro/src/routable_derive.rs | 2 +- packages/yew-router/src/macro_helpers.rs | 3 +- .../yew-router/tests/router_unit_tests.rs | 1 - .../yew-router/tests/url_encoded_routes.rs | 40 +++++++++---------- 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/packages/yew-router-macro/src/routable_derive.rs b/packages/yew-router-macro/src/routable_derive.rs index ae8597a81a2..2dd0804a86b 100644 --- a/packages/yew-router-macro/src/routable_derive.rs +++ b/packages/yew-router-macro/src/routable_derive.rs @@ -129,7 +129,7 @@ impl Routable { Fields::Unit => quote! { Self::#ident }, Fields::Named(field) => { let fields = field.named.iter().map(|it| { - //named fields have idents + // named fields have idents it.ident.as_ref().unwrap() }); quote! { Self::#ident { #(#fields: { diff --git a/packages/yew-router/src/macro_helpers.rs b/packages/yew-router/src/macro_helpers.rs index 71b85b07126..520fae36b8b 100644 --- a/packages/yew-router/src/macro_helpers.rs +++ b/packages/yew-router/src/macro_helpers.rs @@ -1,5 +1,4 @@ -pub use urlencoding::encode as encode_for_url; -pub use urlencoding::decode as decode_for_url; +pub use urlencoding::{decode as decode_for_url, encode as encode_for_url}; use crate::utils::strip_slash_suffix; use crate::Routable; diff --git a/packages/yew-router/tests/router_unit_tests.rs b/packages/yew-router/tests/router_unit_tests.rs index 0f79db55db8..30ad206d2f9 100644 --- a/packages/yew-router/tests/router_unit_tests.rs +++ b/packages/yew-router/tests/router_unit_tests.rs @@ -16,7 +16,6 @@ fn router_always_404() { NotFound, } - assert_eq!( Some(AppRoute::NotFound), AppRoute::recognize("/not/matched/route") diff --git a/packages/yew-router/tests/url_encoded_routes.rs b/packages/yew-router/tests/url_encoded_routes.rs index 304c30ca3a1..482b5bc5f49 100644 --- a/packages/yew-router/tests/url_encoded_routes.rs +++ b/packages/yew-router/tests/url_encoded_routes.rs @@ -1,15 +1,14 @@ use std::time::Duration; + use yew::platform::time::sleep; -use yew_router::prelude::*; use yew::prelude::*; +use yew_router::prelude::*; mod utils; use utils::*; use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure}; wasm_bindgen_test_configure!(run_in_browser); - - #[derive(Routable, Debug, Clone, PartialEq)] enum AppRoute { #[at("/")] @@ -20,20 +19,18 @@ enum AppRoute { #[function_component] fn Comp() -> Html { - let switch = move |routes: AppRoute| { - match routes { - AppRoute::Root => html! { - <> -

{ "Root" }

- to={AppRoute::Search { query: "a/b".to_string() }}> - {"Click me"} - > - - }, - AppRoute::Search { query } => html! { -

{ query }

- }, - } + let switch = move |routes: AppRoute| match routes { + AppRoute::Root => html! { + <> +

{ "Root" }

+ to={AppRoute::Search { query: "a/b".to_string() }}> + {"Click me"} + > + + }, + AppRoute::Search { query } => html! { +

{ query }

+ }, }; html! { render={switch} /> @@ -49,7 +46,6 @@ fn root() -> Html { } } - #[test] async fn url_encoded_roundtrip() { yew::Renderer::::with_root(gloo::utils::document().get_element_by_id("output").unwrap()) @@ -61,7 +57,11 @@ async fn url_encoded_roundtrip() { assert_eq!(res, "a/b"); assert_eq!( - gloo::utils::window().location().pathname().unwrap().to_string(), + gloo::utils::window() + .location() + .pathname() + .unwrap() + .to_string(), "/search/a%2Fb" ) -} \ No newline at end of file +} From 39dd6b4e8ca84e44110f6020027fb5137db40419 Mon Sep 17 00:00:00 2001 From: Muhammad Hamza Date: Tue, 13 Jun 2023 21:42:04 +0500 Subject: [PATCH 10/11] remove redundant to_string --- packages/yew-router/tests/url_encoded_routes.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/yew-router/tests/url_encoded_routes.rs b/packages/yew-router/tests/url_encoded_routes.rs index 482b5bc5f49..03df102f282 100644 --- a/packages/yew-router/tests/url_encoded_routes.rs +++ b/packages/yew-router/tests/url_encoded_routes.rs @@ -60,8 +60,7 @@ async fn url_encoded_roundtrip() { gloo::utils::window() .location() .pathname() - .unwrap() - .to_string(), + .unwrap(), "/search/a%2Fb" ) } From 882c50005ed4efd06768dc0bc5204c271a1077f8 Mon Sep 17 00:00:00 2001 From: Muhammad Hamza Date: Wed, 14 Jun 2023 19:08:49 +0500 Subject: [PATCH 11/11] fmt, please --- packages/yew-router/tests/url_encoded_routes.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/yew-router/tests/url_encoded_routes.rs b/packages/yew-router/tests/url_encoded_routes.rs index 03df102f282..272a1a82599 100644 --- a/packages/yew-router/tests/url_encoded_routes.rs +++ b/packages/yew-router/tests/url_encoded_routes.rs @@ -57,10 +57,7 @@ async fn url_encoded_roundtrip() { assert_eq!(res, "a/b"); assert_eq!( - gloo::utils::window() - .location() - .pathname() - .unwrap(), + gloo::utils::window().location().pathname().unwrap(), "/search/a%2Fb" ) }