From fd7c9e0359823f767f8b90a0b156be4babdb7a22 Mon Sep 17 00:00:00 2001 From: abhi Date: Tue, 2 Jan 2024 16:02:58 +0000 Subject: [PATCH] fix empty render causing panic (#1769) (#1774) * fix empty render causing panic (#1769) * use an default root column instead of an empty root column * fix formatting * restore create.rs in core --------- Co-authored-by: Evan Almloff --- packages/core/src/create.rs | 3 +- packages/rsx/src/lib.rs | 17 ++++--- packages/ssr/src/renderer.rs | 88 ++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 7 deletions(-) diff --git a/packages/core/src/create.rs b/packages/core/src/create.rs index a61a8cace..733a796ce 100644 --- a/packages/core/src/create.rs +++ b/packages/core/src/create.rs @@ -205,7 +205,7 @@ impl<'b> VirtualDom { }); } - /// We write all the descndent data for this element + /// We write all the descendent data for this element /// /// Elements can contain other nodes - and those nodes can be dynamic or static /// @@ -405,6 +405,7 @@ impl<'b> VirtualDom { #[allow(unused_mut)] pub(crate) fn register_template(&mut self, mut template: Template<'static>) { let (path, byte_index) = template.name.rsplit_once(':').unwrap(); + let byte_index = byte_index.parse::().unwrap(); // First, check if we've already seen this template if self diff --git a/packages/rsx/src/lib.rs b/packages/rsx/src/lib.rs index 5db6baee9..458075b63 100644 --- a/packages/rsx/src/lib.rs +++ b/packages/rsx/src/lib.rs @@ -204,12 +204,17 @@ impl<'a> ToTokens for TemplateRenderer<'a> { None => quote! { None }, }; - let spndbg = format!("{:?}", self.roots[0].span()); - let root_col = spndbg - .rsplit_once("..") - .and_then(|(_, after)| after.split_once(')').map(|(before, _)| before)) - .unwrap_or_default(); - + let root_col = match self.roots.first() { + Some(first_root) => { + let first_root_span = format!("{:?}", first_root.span()); + first_root_span + .rsplit_once("..") + .and_then(|(_, after)| after.split_once(')').map(|(before, _)| before)) + .unwrap_or_default() + .to_string() + } + _ => "0".to_string(), + }; let root_printer = self.roots.iter().enumerate().map(|(idx, root)| { context.current_path.push(idx as u8); let out = context.render_static_node(root); diff --git a/packages/ssr/src/renderer.rs b/packages/ssr/src/renderer.rs index 98afef8b7..c0f9b6c75 100644 --- a/packages/ssr/src/renderer.rs +++ b/packages/ssr/src/renderer.rs @@ -238,6 +238,94 @@ fn to_string_works() { assert_eq!(out, "
Hello world 1 -->123<-- Hello world 2
nest 1
nest 2
</diiiiiiiiv>
finalize 0
finalize 1
finalize 2
finalize 3
finalize 4
"); } +#[test] +fn empty_for_loop_works() { + use dioxus::prelude::*; + + fn app(cx: Scope) -> Element { + render! { + div { class: "asdasdasd", + for _ in (0..5) { + + } + } + } + } + + let mut dom = VirtualDom::new(app); + _ = dom.rebuild(); + + let mut renderer = Renderer::new(); + let out = renderer.render(&dom); + + for item in renderer.template_cache.iter() { + if item.1.segments.len() > 5 { + assert_eq!( + item.1.segments, + vec![ + PreRendered("
".into()), + InnerHtmlMarker, + PreRendered("
".into(),), + ] + ); + } + } + + use Segment::*; + + assert_eq!(out, "
"); +} + +#[test] +fn empty_render_works() { + use dioxus::prelude::*; + + fn app(cx: Scope) -> Element { + render! {} + } + + let mut dom = VirtualDom::new(app); + _ = dom.rebuild(); + + let mut renderer = Renderer::new(); + let out = renderer.render(&dom); + + for item in renderer.template_cache.iter() { + if item.1.segments.len() > 5 { + assert_eq!(item.1.segments, vec![]); + } + } + assert_eq!(out, ""); +} + +#[test] +fn empty_rsx_works() { + use dioxus::prelude::*; + + fn app(_: Scope) -> Element { + rsx! {}; + None + } + + let mut dom = VirtualDom::new(app); + _ = dom.rebuild(); + + let mut renderer = Renderer::new(); + let out = renderer.render(&dom); + + for item in renderer.template_cache.iter() { + if item.1.segments.len() > 5 { + assert_eq!(item.1.segments, vec![]); + } + } + assert_eq!(out, ""); +} + pub(crate) const BOOL_ATTRS: &[&str] = &[ "allowfullscreen", "allowpaymentrequest",