wip: fix ssr

This commit is contained in:
Jonathan Kelley committed 2021-12-14 22:48:20 -05:00
1 parent 2fd56e7619
commit ded9696930
7 files changed
+37 -55

No files matched your search

+7 -5
View File
@@ -5,14 +5,16 @@
//! if the type supports PartialEq. The Properties trait is used by the rsx! and html! macros to generate the type-safe builder //! if the type supports PartialEq. The Properties trait is used by the rsx! and html! macros to generate the type-safe builder
//! that ensures compile-time required and optional fields on cx. //! that ensures compile-time required and optional fields on cx.
use crate::innerlude::{Element, LazyNodes, Scope}; use crate::{
innerlude::{Element, Scope},
LazyNodes,
};
pub struct FragmentProps<'a>(Element<'a>); pub struct FragmentProps<'a>(Element<'a>);
pub struct FragmentBuilder<'a, const BUILT: bool>(Element<'a>); pub struct FragmentBuilder<'a, const BUILT: bool>(Element<'a>);
impl<'a> FragmentBuilder<'a, false> { impl<'a> FragmentBuilder<'a, false> {
pub fn children(self, children: Element<'a>) -> FragmentBuilder<'a, true> { pub fn children(self, children: Element<'a>) -> FragmentBuilder<'a, true> {
todo!() FragmentBuilder(children)
// FragmentBuilder(children)
} }
} }
impl<'a, const A: bool> FragmentBuilder<'a, A> { impl<'a, const A: bool> FragmentBuilder<'a, A> {
@@ -99,8 +101,8 @@ impl<'a> Properties for FragmentProps<'a> {
/// You want to use this free-function when your fragment needs a key and simply returning multiple nodes from rsx! won't cut it. /// You want to use this free-function when your fragment needs a key and simply returning multiple nodes from rsx! won't cut it.
#[allow(non_upper_case_globals, non_snake_case)] #[allow(non_upper_case_globals, non_snake_case)]
pub fn Fragment<'a>(cx: Scope<'a, FragmentProps<'a>>) -> Element { pub fn Fragment<'a>(cx: Scope<'a, FragmentProps<'a>>) -> Element {
todo!() let i = cx.props.0.as_ref().map(|f| f.decouple());
// cx.render(Some(LazyNodes::new(|f| f.fragment_from_iter(&cx.props.0)))) cx.render(Some(LazyNodes::new(|f| f.fragment_from_iter(i))))
} }
/// Every "Props" used for a component must implement the `Properties` trait. This trait gives some hints to Dioxus /// Every "Props" used for a component must implement the `Properties` trait. This trait gives some hints to Dioxus
+1 -1
View File
@@ -42,7 +42,7 @@ pub mod prelude {
pub mod exports { pub mod exports {
//! Important dependencies that are used by the rest of the library //! Important dependencies that are used by the rest of the library
// the foundation of this library //! Feel free to just add the dependencies in your own Crates.toml
pub use bumpalo; pub use bumpalo;
pub use futures_channel; pub use futures_channel;
} }
+13
View File
@@ -774,3 +774,16 @@ impl IntoVNode<'_> for Arguments<'_> {
cx.text(self) cx.text(self)
} }
} }
impl<'a> IntoVNode<'a> for &Option<VNode<'a>> {
fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> {
let r = self.as_ref().map(|f| f.decouple());
cx.fragment_from_iter(r)
}
}
impl<'a> IntoVNode<'a> for &VNode<'a> {
fn into_vnode(self, _cx: NodeFactory<'a>) -> VNode<'a> {
self.decouple()
}
}
+1 -30
View File
@@ -136,30 +136,7 @@ impl ScopeArena {
} }
}; };
let mut frames = [BumpFrame::new(node_capacity), BumpFrame::new(node_capacity)]; let frames = [BumpFrame::new(node_capacity), BumpFrame::new(node_capacity)];
// todo - add the node
// frames[0].nodes.get_mut().push({
// let vnode = frames[0]
// .bump
// .alloc(VNode::Text(frames[0].bump.alloc(VText {
// dom_id: Default::default(),
// is_static: false,
// text: "",
// })));
// unsafe { std::mem::transmute(vnode as *mut VNode) }
// });
// frames[1].nodes.get_mut().push({
// let vnode = frames[1]
// .bump
// .alloc(VNode::Text(frames[1].bump.alloc(VText {
// dom_id: Default::default(),
// is_static: false,
// text: "",
// })));
// unsafe { std::mem::transmute(vnode as *mut VNode) }
// });
let scope = self.bump.alloc(ScopeState { let scope = self.bump.alloc(ScopeState {
sender: self.sender.clone(), sender: self.sender.clone(),
@@ -217,9 +194,6 @@ impl ScopeArena {
scope.is_subtree_root.set(false); scope.is_subtree_root.set(false);
scope.subtree.set(0); scope.subtree.set(0);
// scope.frames[0].nodes.get_mut().clear();
// scope.frames[1].nodes.get_mut().clear();
scope.frames[0].bump.reset(); scope.frames[0].bump.reset();
scope.frames[1].bump.reset(); scope.frames[1].bump.reset();
@@ -258,8 +232,6 @@ impl ScopeArena {
self.nodes.borrow_mut().remove(id.0); self.nodes.borrow_mut().remove(id.0);
} }
// These methods would normally exist on `scope` but they need access to *all* of the scopes
/// This method cleans up any references to data held within our hook list. This prevents mutable aliasing from /// This method cleans up any references to data held within our hook list. This prevents mutable aliasing from
/// causing UB in our tree. /// causing UB in our tree.
/// ///
@@ -379,7 +351,6 @@ impl ScopeArena {
pub fn wip_head(&self, id: ScopeId) -> &VNode { pub fn wip_head(&self, id: ScopeId) -> &VNode {
let scope = self.get_scope(id).unwrap(); let scope = self.get_scope(id).unwrap();
let frame = scope.wip_frame(); let frame = scope.wip_frame();
let nodes = frame.nodes.borrow();
let node = unsafe { &*frame.nodes.get() }; let node = unsafe { &*frame.nodes.get() };
unsafe { std::mem::transmute::<&VNode, &VNode>(node) } unsafe { std::mem::transmute::<&VNode, &VNode>(node) }
} }
+1 -2
View File
@@ -221,10 +221,9 @@ fn create_components() {
} }
fn Child<'a>(cx: Scope<'a, ChildProps<'a>>) -> Element { fn Child<'a>(cx: Scope<'a, ChildProps<'a>>) -> Element {
todo!();
cx.render(rsx! { cx.render(rsx! {
h1 {} h1 {}
// div { {&cx.props.children} } div { {&cx.props.children} }
p {} p {}
}) })
} }
+7 -7
View File
@@ -141,7 +141,7 @@ fn components_generate() {
] ]
); );
let edits = dom.hard_diff(&ScopeId(0)).unwrap(); let edits = dom.hard_diff(ScopeId(0)).unwrap();
assert_eq!( assert_eq!(
edits.edits, edits.edits,
[ [
@@ -153,7 +153,7 @@ fn components_generate() {
] ]
); );
let edits = dom.hard_diff(&ScopeId(0)).unwrap(); let edits = dom.hard_diff(ScopeId(0)).unwrap();
assert_eq!( assert_eq!(
edits.edits, edits.edits,
[ [
@@ -165,7 +165,7 @@ fn components_generate() {
] ]
); );
let edits = dom.hard_diff(&ScopeId(0)).unwrap(); let edits = dom.hard_diff(ScopeId(0)).unwrap();
assert_eq!( assert_eq!(
edits.edits, edits.edits,
[ [
@@ -174,13 +174,13 @@ fn components_generate() {
] ]
); );
let edits = dom.hard_diff(&ScopeId(0)).unwrap(); let edits = dom.hard_diff(ScopeId(0)).unwrap();
assert_eq!( assert_eq!(
edits.edits, edits.edits,
[CreatePlaceholder { root: 5 }, ReplaceWith { root: 4, m: 1 },] [CreatePlaceholder { root: 5 }, ReplaceWith { root: 4, m: 1 },]
); );
let edits = dom.hard_diff(&ScopeId(0)).unwrap(); let edits = dom.hard_diff(ScopeId(0)).unwrap();
assert_eq!( assert_eq!(
edits.edits, edits.edits,
[ [
@@ -192,7 +192,7 @@ fn components_generate() {
] ]
); );
let edits = dom.hard_diff(&ScopeId(0)).unwrap(); let edits = dom.hard_diff(ScopeId(0)).unwrap();
assert_eq!( assert_eq!(
edits.edits, edits.edits,
[ [
@@ -208,7 +208,7 @@ fn components_generate() {
] ]
); );
let edits = dom.hard_diff(&ScopeId(0)).unwrap(); let edits = dom.hard_diff(ScopeId(0)).unwrap();
assert_eq!( assert_eq!(
edits.edits, edits.edits,
[ [
+7 -10
View File
@@ -94,7 +94,7 @@ pub fn render_vdom_scope(vdom: &VirtualDom, scope: ScopeId) -> Option<String> {
"{:}", "{:}",
TextRenderer { TextRenderer {
cfg: SsrConfig::default(), cfg: SsrConfig::default(),
root: vdom.get_scope(&scope).unwrap().root_node(), root: vdom.get_scope(scope).unwrap().root_node(),
vdom: Some(vdom) vdom: Some(vdom)
} }
)) ))
@@ -158,9 +158,6 @@ impl<'a> TextRenderer<'a, '_> {
} }
write!(f, "<!-- -->")?; write!(f, "<!-- -->")?;
} }
VNode::Portal(link) => {
todo!();
}
VNode::Element(el) => { VNode::Element(el) => {
if self.cfg.indent { if self.cfg.indent {
for _ in 0..il { for _ in 0..il {
@@ -247,7 +244,7 @@ impl<'a> TextRenderer<'a, '_> {
let idx = vcomp.associated_scope.get().unwrap(); let idx = vcomp.associated_scope.get().unwrap();
if let (Some(vdom), false) = (self.vdom, self.cfg.skip_components) { if let (Some(vdom), false) = (self.vdom, self.cfg.skip_components) {
let new_node = vdom.get_scope(&idx).unwrap().root_node(); let new_node = vdom.get_scope(idx).unwrap().root_node();
self.html_render(new_node, f, il + 1)?; self.html_render(new_node, f, il + 1)?;
} else { } else {
} }
@@ -301,13 +298,13 @@ mod tests {
use dioxus_core_macro::*; use dioxus_core_macro::*;
use dioxus_html as dioxus_elements; use dioxus_html as dioxus_elements;
static SIMPLE_APP: Component<()> = |cx, _| { static SIMPLE_APP: Component<()> = |cx| {
cx.render(rsx!(div { cx.render(rsx!(div {
"hello world!" "hello world!"
})) }))
}; };
static SLIGHTLY_MORE_COMPLEX: Component<()> = |cx, _| { static SLIGHTLY_MORE_COMPLEX: Component<()> = |cx| {
cx.render(rsx! { cx.render(rsx! {
div { div {
title: "About W3Schools" title: "About W3Schools"
@@ -326,14 +323,14 @@ mod tests {
}) })
}; };
static NESTED_APP: Component<()> = |cx, _| { static NESTED_APP: Component<()> = |cx| {
cx.render(rsx!( cx.render(rsx!(
div { div {
SIMPLE_APP {} SIMPLE_APP {}
} }
)) ))
}; };
static FRAGMENT_APP: Component<()> = |cx, _| { static FRAGMENT_APP: Component<()> = |cx| {
cx.render(rsx!( cx.render(rsx!(
div { "f1" } div { "f1" }
div { "f2" } div { "f2" }
@@ -389,7 +386,7 @@ mod tests {
#[test] #[test]
fn styles() { fn styles() {
static STLYE_APP: Component<()> = |cx, _| { static STLYE_APP: Component<()> = |cx| {
cx.render(rsx! { cx.render(rsx! {
div { color: "blue", font_size: "46px" } div { color: "blue", font_size: "46px" }
}) })