feat: todomvc
This commit is contained in:
1 parent
ce33031519
commit
cfa0927cdd
20 files changed
+934
-245
No files matched your search
+21
-21
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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 _,
|
||||
|
||||
Reference in new issue
Block a user