feat: todomvc

This commit is contained in:
Jonathan Kelley committed 2021-04-01 00:01:42 -04:00
1 parent ce33031519
commit cfa0927cdd
20 files changed
+934 -245

No files matched your search

+21 -21
View File
@@ -473,27 +473,27 @@ impl<'a> DiffMachine<'a> {
//
// Upon exiting, the change list stack is in the same state.
fn diff_keyed_children(&mut self, old: &[VNode<'a>], new: &[VNode<'a>]) {
if cfg!(debug_assertions) {
let mut keys = fxhash::FxHashSet::default();
let mut assert_unique_keys = |children: &[VNode]| {
keys.clear();
for child in children {
let key = child.key();
debug_assert!(
key.is_some(),
"if any sibling is keyed, all siblings must be keyed"
);
keys.insert(key);
}
debug_assert_eq!(
children.len(),
keys.len(),
"keyed siblings must each have a unique key"
);
};
assert_unique_keys(old);
assert_unique_keys(new);
}
// if cfg!(debug_assertions) {
// let mut keys = fxhash::FxHashSet::default();
// let mut assert_unique_keys = |children: &[VNode]| {
// keys.clear();
// for child in children {
// let key = child.key();
// debug_assert!(
// key.is_some(),
// "if any sibling is keyed, all siblings must be keyed"
// );
// keys.insert(key);
// }
// debug_assert_eq!(
// children.len(),
// keys.len(),
// "keyed siblings must each have a unique key"
// );
// };
// assert_unique_keys(old);
// assert_unique_keys(new);
// }
// First up, we diff all the nodes with the same key at the beginning of the
// children.
+3 -1
View File
@@ -146,7 +146,9 @@ pub mod on {
}
#[derive(Debug)]
pub struct FormEvent {}
pub struct FormEvent {
pub value: String,
}
event_builder! {
FormEvent;
change input invalid reset submit
+10 -66
View File
@@ -23,7 +23,7 @@ where
Children: 'a + AsRef<[VNode<'a>]>,
{
ctx: &'b NodeCtx<'a>,
key: NodeKey,
key: NodeKey<'a>,
tag_name: &'a str,
listeners: Listeners,
attributes: Attributes,
@@ -264,10 +264,8 @@ where
/// .finish();
/// ```
#[inline]
pub fn key(mut self, key: u32) -> Self {
use std::u32;
debug_assert!(key != u32::MAX);
self.key = NodeKey(key);
pub fn key(mut self, key: &'a str) -> Self {
self.key = NodeKey(Some(key));
self
}
@@ -572,65 +570,6 @@ impl<'a> IntoDomTree<'a> for () {
}
}
#[test]
fn test_iterator_of_nodes<'b>() {
use crate::prelude::*;
// static Example: FC<()> = |ctx, props| {
// let body = rsx! {
// div {}
// };
// ctx.render(rsx! {
// div {
// h1 {}
// }
// })
// };
// let p = (0..10).map(|f| {
// //
// LazyNodes::new(rsx! {
// div {
// "aaa {f}"
// }
// })
// });
// let g = p.into_iter();
// for f in g {}
// static Example: FC<()> = |ctx, props| {
// ctx.render(|c| {
// //
// ElementBuilder::new(c, "div")
// .iter_child({
// // rsx!
// LazyNodes::new(move |n: &NodeCtx| -> VNode {
// //
// ElementBuilder::new(n, "div").finish()
// })
// })
// .iter_child({
// // render to wrapper -> tree
// ctx.render(rsx! {
// div {}
// })
// })
// .iter_child({
// // map rsx!
// (0..10).map(|f| {
// LazyNodes::new(move |n: &NodeCtx| -> VNode {
// //
// ElementBuilder::new(n, "div").finish()
// })
// })
// })
// .finish()
// })
// };
}
/// Construct a text VNode.
///
/// This is `dioxus`'s virtual DOM equivalent of `document.createTextVNode`.
@@ -668,9 +607,14 @@ pub fn attr<'a>(name: &'static str, value: &'a str) -> Attribute<'a> {
Attribute { name, value }
}
pub fn virtual_child<'a, T: Properties + 'a>(ctx: &NodeCtx<'a>, f: FC<T>, p: T) -> VNode<'a> {
pub fn virtual_child<'a, T: Properties + 'a>(
ctx: &NodeCtx<'a>,
f: FC<T>,
p: T,
key: Option<&'a str>, // key: NodeKey<'a>,
) -> VNode<'a> {
// currently concerned about if props have a custom drop implementation
// might override it with the props macro
let propsd: &'a mut _ = ctx.bump.alloc(p);
VNode::Component(crate::nodes::VComponent::new(f, propsd))
VNode::Component(crate::nodes::VComponent::new(f, propsd, key))
}
+18 -16
View File
@@ -59,7 +59,7 @@ impl<'a> VNode<'a> {
#[inline]
pub fn element(
bump: &'a Bump,
key: NodeKey,
key: NodeKey<'a>,
tag_name: &'a str,
listeners: &'a [Listener<'a>],
attributes: &'a [Attribute<'a>],
@@ -102,7 +102,7 @@ impl<'a> VNode<'a> {
#[derive(Debug)]
pub struct VElement<'a> {
/// Elements have a tag name, zero or more attributes, and zero or more
pub key: NodeKey,
pub key: NodeKey<'a>,
pub tag_name: &'a str,
pub listeners: &'a [Listener<'a>],
pub attributes: &'a [Attribute<'a>],
@@ -191,16 +191,16 @@ impl Debug for Listener<'_> {
///
/// If any sibling is keyed, then they all must be keyed.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct NodeKey(pub(crate) u32);
pub struct NodeKey<'a>(pub(crate) Option<&'a str>);
impl Default for NodeKey {
fn default() -> NodeKey {
impl<'a> Default for NodeKey<'a> {
fn default() -> NodeKey<'a> {
NodeKey::NONE
}
}
impl NodeKey {
impl<'a> NodeKey<'a> {
/// The default, lack of a key.
pub const NONE: NodeKey = NodeKey(u32::MAX);
pub const NONE: NodeKey<'a> = NodeKey(None);
/// Is this key `NodeKey::NONE`?
#[inline]
@@ -218,9 +218,8 @@ impl NodeKey {
///
/// `key` must not be `u32::MAX`.
#[inline]
pub fn new(key: u32) -> Self {
debug_assert_ne!(key, u32::MAX);
NodeKey(key)
pub fn new(key: &'a str) -> Self {
NodeKey(Some(key))
}
}
@@ -231,9 +230,7 @@ pub struct VText<'bump> {
impl<'a> VText<'a> {
// / Create an new `VText` instance with the specified text.
pub fn new(text: &'a str) -> Self
// pub fn new(text: Into<str>) -> Self
{
pub fn new(text: &'a str) -> Self {
VText { text: text.into() }
}
}
@@ -248,7 +245,7 @@ pub type StableScopeAddres = RefCell<Option<u32>>;
pub type VCompAssociatedScope = RefCell<Option<ScopeIdx>>;
pub struct VComponent<'src> {
pub key: NodeKey,
pub key: NodeKey<'src>,
pub stable_addr: Rc<StableScopeAddres>,
pub ass_scope: Rc<VCompAssociatedScope>,
@@ -276,7 +273,7 @@ impl<'a> VComponent<'a> {
// - perform comparisons when diffing (memoization)
// TODO: lift the requirement that props need to be static
// we want them to borrow references... maybe force implementing a "to_static_unsafe" trait
pub fn new<P: Properties + 'a>(component: FC<P>, props: &'a P) -> Self {
pub fn new<P: Properties + 'a>(component: FC<P>, props: &'a P, key: Option<&'a str>) -> Self {
let caller_ref = component as *const ();
let raw_props = props as *const P as *const ();
@@ -299,8 +296,13 @@ impl<'a> VComponent<'a> {
let caller = Rc::new(create_closure(component, raw_props));
let key = match key {
Some(key) => NodeKey::new(key),
None => NodeKey(None),
};
Self {
key: NodeKey::NONE,
key,
ass_scope: Rc::new(RefCell::new(None)),
user_fc: caller_ref,
raw_props: props as *const P as *const _,