wip: more work on diffing machine

This commit is contained in:
Jonathan Kelley 2021-06-26 22:13:57 -04:00
parent ca3b80f069
commit 9813f23cdf
9 changed files with 172 additions and 299 deletions

View file

@ -55,7 +55,7 @@ members = [
"packages/core-macro",
"packages/core",
"packages/html-namespace",
# "packages/web",
"packages/web",
# "packages/cli",
# "packages/atoms",
# "packages/ssr",

View file

@ -4,15 +4,15 @@
//! Notice:
//! ------
//!
//! The inspiration and code for this module was originally taken from Dodrio (@fitzgen) and modified to support Components,
//! Fragments, Suspense, and additional batching operations.
//! The inspiration and code for this module was originally taken from Dodrio (@fitzgen) and then modified to support
//! Components, Fragments, Suspense, and additional batching operations.
//!
//! Implementation Details:
//! -----------------------
//!
//! All nodes are addressed by their IDs. The RealDom provides an imperative interface for making changes to these nodes.
//! We don't necessarily intend for changes to happen exactly during the diffing process, so the implementor may choose
//! to batch nodes if it is more performant for their application. The u32 should be a no-op to hash,
//! We don't necessarily require that DOM changes happen instnatly during the diffing process, so the implementor may choose
//! to batch nodes if it is more performant for their application. We care about an ID size of u32
//!
//!
//! Further Reading and Thoughts
@ -58,6 +58,8 @@ pub trait RealDom {
fn create_text_node(&mut self, text: &str) -> RealDomNode;
fn create_element(&mut self, tag: &str) -> RealDomNode;
fn create_element_ns(&mut self, tag: &str, namespace: &str) -> RealDomNode;
// placeholders are nodes that don't get rendered but still exist as an "anchor" in the real dom
fn create_placeholder(&mut self) -> RealDomNode;
// events
fn new_event_listener(
@ -152,7 +154,6 @@ impl<'a, Dom: RealDom> DiffMachine<'a, Dom> {
}
// New node is a text element, need to replace the element with a simple text node
VNode::Text(_) => {
log::debug!("Replacing el with text");
self.create(new_node);
self.dom.replace_with();
}
@ -167,10 +168,22 @@ impl<'a, Dom: RealDom> DiffMachine<'a, Dom> {
// New node is actually a sequence of nodes.
// We need to replace this one node with a sequence of nodes
// Not yet implement because it's kinda hairy
VNode::Fragment(_) => todo!(),
VNode::Fragment(new) => {
match new.children.len() {
0 => {
// remove
}
1 => {
// replace
}
_ => {
// remove and mount many
}
}
}
// New Node is actually suspended. Todo
VNode::Suspended => todo!(),
VNode::Suspended { real } => todo!(),
},
// Old element was text
@ -200,7 +213,7 @@ impl<'a, Dom: RealDom> DiffMachine<'a, Dom> {
}
}
}
VNode::Suspended => todo!(),
VNode::Suspended { real } => todo!(),
},
// Old element was a component
@ -214,75 +227,74 @@ impl<'a, Dom: RealDom> DiffMachine<'a, Dom> {
// It's also a component
VNode::Component(new) => {
match old.user_fc == new.user_fc {
if old.user_fc == new.user_fc {
// Make sure we're dealing with the same component (by function pointer)
true => {
// Make sure the new component vnode is referencing the right scope id
let scope_id = old.ass_scope.borrow().clone();
*new.ass_scope.borrow_mut() = scope_id;
// make sure the component's caller function is up to date
// Make sure the new component vnode is referencing the right scope id
let scope_id = old.ass_scope.borrow().clone();
*new.ass_scope.borrow_mut() = scope_id;
// make sure the component's caller function is up to date
self.components
.with_scope(scope_id.unwrap(), |scope| {
scope.caller = Rc::downgrade(&new.caller)
})
.unwrap();
// React doesn't automatically memoize, but we do.
// The cost is low enough to make it worth checking
let should_render = match old.comparator {
Some(comparator) => comparator(new),
None => true,
};
if should_render {
// // self.dom.commit_traversal();
self.components
.with_scope(scope_id.unwrap(), |scope| {
scope.caller = Rc::downgrade(&new.caller)
.with_scope(scope_id.unwrap(), |f| {
f.run_scope().unwrap();
})
.unwrap();
// React doesn't automatically memoize, but we do.
// The cost is low enough to make it worth checking
let should_render = match old.comparator {
Some(comparator) => comparator(new),
None => true,
};
if should_render {
// // self.dom.commit_traversal();
self.components
.with_scope(scope_id.unwrap(), |f| {
f.run_scope().unwrap();
})
.unwrap();
// diff_machine.change_list.load_known_root(root_id);
// run the scope
//
} else {
// Component has memoized itself and doesn't need to be re-rendered.
// We still need to make sure the child's props are up-to-date.
// Don't commit traversal
}
// diff_machine.change_list.load_known_root(root_id);
// run the scope
//
} else {
// Component has memoized itself and doesn't need to be re-rendered.
// We still need to make sure the child's props are up-to-date.
// Don't commit traversal
}
} else {
// It's an entirely different component
false => {
// A new component has shown up! We need to destroy the old node
// Wipe the old one and plant the new one
// self.dom.commit_traversal();
// self.dom.replace_node_with(old.dom_id, new.dom_id);
// self.create(new_node);
// self.dom.replace_with();
self.create(new_node);
// self.create_and_repalce(new_node, old.mounted_root.get());
// A new component has shown up! We need to destroy the old node
// Now we need to remove the old scope and all of its descendents
let old_scope = old.ass_scope.borrow().as_ref().unwrap().clone();
self.destroy_scopes(old_scope);
}
// Wipe the old one and plant the new one
// self.dom.commit_traversal();
// self.dom.replace_node_with(old.dom_id, new.dom_id);
// self.create(new_node);
// self.dom.replace_with();
self.create(new_node);
// self.create_and_repalce(new_node, old.mounted_root.get());
// Now we need to remove the old scope and all of its descendents
let old_scope = old.ass_scope.borrow().as_ref().unwrap().clone();
self.destroy_scopes(old_scope);
}
}
VNode::Fragment(_) => todo!(),
VNode::Suspended => todo!(),
VNode::Suspended { real } => todo!(),
}
}
VNode::Fragment(old) => {
//
match new_node {
VNode::Fragment(_) => todo!(),
VNode::Fragment(new) => todo!(),
// going from fragment to element means we're going from many (or potentially none) to one
VNode::Element(new) => {}
VNode::Text(_) => todo!(),
VNode::Suspended => todo!(),
VNode::Suspended { real } => todo!(),
VNode::Component(_) => todo!(),
}
}
@ -290,10 +302,12 @@ impl<'a, Dom: RealDom> DiffMachine<'a, Dom> {
// a suspended node will perform a mem-copy of the previous elements until it is ready
// this means that event listeners will need to be disabled and removed
// it also means that props will need to disabled - IE if the node "came out of hibernation" any props should be considered outdated
VNode::Suspended => {
VNode::Suspended { real: old_real } => {
//
match new_node {
VNode::Suspended => todo!(),
VNode::Suspended { real: new_real } => {
//
}
VNode::Element(_) => todo!(),
VNode::Text(_) => todo!(),
VNode::Fragment(_) => todo!(),
@ -354,6 +368,10 @@ impl<'a, Dom: RealDom> DiffMachine<'a, Dom> {
// to emit three instructions to (1) create a text node, (2) set its
// text content, and finally (3) append the text node to this
// parent.
//
// Notice: this is a web-specific optimization and may be changed in the future
//
// TODO move over
// if children.len() == 1 {
// if let VNode::Text(text) = &children[0] {
// self.dom.set_text(text.text);
@ -373,7 +391,7 @@ impl<'a, Dom: RealDom> DiffMachine<'a, Dom> {
}
VNode::Component(component) => {
self.dom.create_text_node("placeholder for vcomponent");
let real_id = self.dom.create_placeholder();
// let root_id = next_id();
// self.dom.save_known_root(root_id);
@ -426,7 +444,6 @@ impl<'a, Dom: RealDom> DiffMachine<'a, Dom> {
new_component.run_scope().unwrap();
// And then run the diff algorithm
// todo!();
self.diff_node(new_component.old_frame(), new_component.next_frame());
// Finally, insert this node as a seen node.
@ -437,21 +454,17 @@ impl<'a, Dom: RealDom> DiffMachine<'a, Dom> {
VNode::Fragment(frag) => {
// create the children directly in the space
for child in frag.children {
todo!()
// self.create(child);
// self.dom.append_child();
self.create(child);
self.dom.append_child();
}
}
VNode::Suspended => {
todo!("Creation of VNode::Suspended not yet supported")
VNode::Suspended { real } => {
let id = self.dom.create_placeholder();
real.set(id);
}
}
}
fn iter_children(&self, node: &VNode<'a>) -> ChildIterator<'a> {
todo!()
}
}
impl<'a, Dom: RealDom> DiffMachine<'a, Dom> {
@ -680,29 +693,29 @@ impl<'a, Dom: RealDom> DiffMachine<'a, Dom> {
// [... parent]
//
// Upon exiting, the change list stack is in the same state.
fn diff_keyed_children(&self, old: &[VNode<'a>], new: &[VNode<'a>]) {
todo!();
// 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);
// }
fn diff_keyed_children(&self, old: &'a [VNode<'a>], new: &'a [VNode<'a>]) {
// todo!();
if cfg!(debug_assertions) {
let mut keys = fxhash::FxHashSet::default();
let mut assert_unique_keys = |children: &'a [VNode<'a>]| {
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.
@ -1090,7 +1103,12 @@ impl<'a, Dom: RealDom> DiffMachine<'a, Dom> {
// [... parent prev_child]
// self.dom.go_to_sibling(i);
// [... parent this_child]
self.dom.push_root(old_child.get_mounted_id().unwrap());
let did = old_child.get_mounted_id().unwrap();
if did.0 == 0 {
log::debug!("Root is bad {:#?}", old_child);
}
self.dom.push_root(did);
self.diff_node(old_child, new_child);
let old_id = old_child.get_mounted_id().unwrap();
@ -1270,7 +1288,7 @@ impl<'a> Iterator for ChildIterator<'a> {
// Immediately abort suspended nodes - can't do anything with them yet
// VNode::Suspended => should_pop = true,
VNode::Suspended => todo!(),
VNode::Suspended { real } => todo!(),
// For components, we load their root and push them onto the stack
VNode::Component(sc) => {
@ -1370,7 +1388,7 @@ mod tests {
// These would represent failing cases.
VNode::Fragment(_) => panic!("Found: Fragment"),
VNode::Suspended => panic!("Found: Suspended"),
VNode::Suspended { real } => panic!("Found: Suspended"),
VNode::Component(_) => panic!("Found: Component"),
}
}

View file

@ -611,14 +611,18 @@ where
impl<'a> IntoVNode<'a> for () {
fn into_vnode(self, cx: &NodeCtx<'a>) -> VNode<'a> {
todo!();
VNode::Suspended
VNode::Suspended {
real: Cell::new(RealDomNode::empty()),
}
}
}
impl<'a> IntoVNode<'a> for Option<()> {
fn into_vnode(self, cx: &NodeCtx<'a>) -> VNode<'a> {
todo!();
VNode::Suspended
VNode::Suspended {
real: Cell::new(RealDomNode::empty()),
}
}
}

View file

@ -35,7 +35,7 @@ pub enum VNode<'src> {
/// A "suspended component"
/// This is a masqeurade over an underlying future that needs to complete
/// When the future is completed, the VNode will then trigger a render
Suspended,
Suspended { real: Cell<RealDomNode> },
/// A User-defined componen node (node type COMPONENT_NODE)
Component(&'src VComponent<'src>),
@ -49,7 +49,7 @@ impl<'a> Clone for VNode<'a> {
VNode::Text(old) => VNode::Text(old.clone()),
VNode::Fragment(fragment) => VNode::Fragment(fragment),
VNode::Component(component) => VNode::Component(component),
VNode::Suspended => VNode::Suspended,
VNode::Suspended { real } => VNode::Suspended { real: real.clone() },
}
}
}
@ -85,7 +85,7 @@ impl<'old, 'new> VNode<'old> {
}
VNode::Text(_) => todo!(),
VNode::Fragment(_) => todo!(),
VNode::Suspended => todo!(),
VNode::Suspended { real } => todo!(),
VNode::Component(_) => todo!(),
}
}
@ -142,7 +142,7 @@ impl<'a> VNode<'a> {
VNode::Component(c) => c.key,
// todo suspend should be allowed to have keys
VNode::Suspended => NodeKey::NONE,
VNode::Suspended { .. } => NodeKey::NONE,
}
}
@ -155,7 +155,7 @@ impl<'a> VNode<'a> {
VNode::Element(_) => true,
VNode::Text(_) => true,
VNode::Fragment(_) => false,
VNode::Suspended => false,
VNode::Suspended { .. } => false,
VNode::Component(_) => false,
}
}
@ -165,7 +165,7 @@ impl<'a> VNode<'a> {
VNode::Element(el) => Some(el.dom_id.get()),
VNode::Text(te) => Some(te.dom_id.get()),
VNode::Fragment(_) => todo!(),
VNode::Suspended => todo!(),
VNode::Suspended { .. } => todo!(),
VNode::Component(_) => todo!(),
}
}
@ -177,7 +177,7 @@ impl Debug for VNode<'_> {
VNode::Element(el) => write!(s, "element, {}", el.tag_name),
VNode::Text(t) => write!(s, "text, {}", t.text),
VNode::Fragment(_) => write!(s, "fragment"),
VNode::Suspended => write!(s, "suspended"),
VNode::Suspended { .. } => write!(s, "suspended"),
VNode::Component(_) => write!(s, "component"),
}
}
@ -436,163 +436,3 @@ impl<'a> VFragment<'a> {
Self { key, children }
}
}
// /// This method converts a list of nested real/virtual nodes into a stream of nodes that are definitely associated
// /// with the real dom. The only types of nodes that may be returned are text, elemets, and components.
// ///
// /// Components *are* considered virtual, but this iterator can't necessarily handle them without the scope arena.
// ///
// /// Why?
// /// ---
// /// Fragments are seen as virtual nodes but are actually a list of possibly-real nodes.
// /// JS implementations normalize their node lists when fragments are present. Here, we just create a new iterator
// /// that iterates through the recursive nesting of fragments.
// ///
// /// Fragments are stupid and I wish we didn't need to support them.
// ///
// /// This iterator only supports 3 levels of nested fragments
// ///
// pub fn iterate_real_nodes<'a>(nodes: &'a [VNode<'a>]) -> RealNodeIterator<'a> {
// RealNodeIterator::new(nodes)
// }
// pub struct RealNodeIterator<'a> {
// nodes: &'a [VNode<'a>],
// // this node is always a "real" node
// // the index is "what sibling # is it"
// // IE in a list of children on a fragment, the node will be a text node that's the 5th sibling
// node_stack: Vec<(&'a VNode<'a>, u32)>,
// }
// impl<'a> RealNodeIterator<'a> {
// // We immediately descend to the first real node we can find
// fn new(nodes: &'a [VNode<'a>]) -> Self {
// let mut node_stack = Vec::new();
// if nodes.len() > 0 {
// let mut cur_node = nodes.get(0).unwrap();
// loop {
// node_stack.push((cur_node, 0_u32));
// if !cur_node.is_real() {
// cur_node = cur_node.get_child(0).unwrap();
// } else {
// break;
// }
// }
// }
// Self { nodes, node_stack }
// }
// // // advances the cursor to the next element, panicing if we're on the 3rd level and still finding fragments
// // fn advance_cursor(&mut self) {
// // let (mut cur_node, mut cur_id) = self.node_stack.last().unwrap();
// // while !cur_node.is_real() {
// // match cur_node {
// // VNode::Element(_) | VNode::Text(_) => todo!(),
// // VNode::Suspended => todo!(),
// // VNode::Component(_) => todo!(),
// // VNode::Fragment(frag) => {
// // let p = frag.children;
// // }
// // }
// // }
// // }
// fn next_node(&mut self) -> bool {
// let (mut cur_node, cur_id) = self.node_stack.last_mut().unwrap();
// match cur_node {
// VNode::Fragment(frag) => {
// //
// if *cur_id + 1 > frag.children.len() as u32 {
// self.node_stack.pop();
// let next = self.node_stack.last_mut();
// return false;
// }
// *cur_id += 1;
// true
// }
// VNode::Element(_) => todo!(),
// VNode::Text(_) => todo!(),
// VNode::Suspended => todo!(),
// VNode::Component(_) => todo!(),
// }
// }
// fn get_current_node(&self) -> Option<&VNode<'a>> {
// self.node_stack.last().map(|(node, id)| match node {
// VNode::Element(_) => todo!(),
// VNode::Text(_) => todo!(),
// VNode::Fragment(_) => todo!(),
// VNode::Suspended => todo!(),
// VNode::Component(_) => todo!(),
// })
// }
// }
// impl<'a> Iterator for RealNodeIterator<'a> {
// type Item = &'a VNode<'a>;
// fn next(&mut self) -> Option<Self::Item> {
// todo!()
// // let top_idx = self.nesting_idxs.get_mut(0).unwrap();
// // let node = &self.nodes.get_mut(*top_idx as usize);
// // if node.is_none() {
// // return None;
// // }
// // let node = node.unwrap();
// // match node {
// // VNode::Element(_) | VNode::Text(_) => {
// // *top_idx += 1;
// // return Some(node);
// // }
// // VNode::Suspended => todo!(),
// // // we need access over the scope map
// // VNode::Component(_) => todo!(),
// // VNode::Fragment(frag) => {
// // let nest_idx = self.nesting_idxs.get_mut(1).unwrap();
// // let node = &frag.children.get_mut(*nest_idx as usize);
// // match node {
// // VNode::Element(_) | VNode::Text(_) => {
// // *nest_idx += 1;
// // return Some(node);
// // }
// // VNode::Fragment(_) => todo!(),
// // VNode::Suspended => todo!(),
// // VNode::Component(_) => todo!(),
// // }
// // }
// // }
// }
// }
mod tests {
use crate::debug_renderer::DebugRenderer;
use crate::nodebuilder::LazyNodes;
use crate as dioxus;
use dioxus::prelude::*;
#[test]
fn iterate_nodes() {
let rs = rsx! {
Fragment {
Fragment {
Fragment {
Fragment {
h1 {"abc1"}
}
h2 {"abc2"}
}
h3 {"abc3"}
}
h4 {"abc4"}
}
};
}
}

View file

@ -1,7 +1,7 @@
use crate::innerlude::*;
pub struct DebugDom {
counter: u32,
counter: u64,
}
impl DebugDom {
pub fn new() -> Self {
@ -33,6 +33,10 @@ impl RealDom for DebugDom {
self.counter += 1;
RealDomNode::new(self.counter)
}
fn create_placeholder(&mut self) -> RealDomNode {
self.counter += 1;
RealDomNode::new(self.counter)
}
fn new_event_listener(
&mut self,

View file

@ -64,14 +64,19 @@ pub struct VirtualDom {
_root_prop_type: std::any::TypeId,
}
/// The `RealDomNode` is an ID handle that corresponds to a foreign DOM node.
///
/// "u64" was chosen for two reasons
/// - 0 cost hashing
/// - use with slotmap and other versioned slot arenas
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct RealDomNode(pub u32);
pub struct RealDomNode(pub u64);
impl RealDomNode {
pub fn new(id: u32) -> Self {
pub fn new(id: u64) -> Self {
Self(id)
}
pub fn empty() -> Self {
Self(u32::MIN)
Self(u64::MIN)
}
}
@ -795,7 +800,7 @@ Any function prefixed with "use" should not be called conditionally.
}
/// There are hooks going on here!
fn use_context<T: 'static>(&self) -> &'src T {
fn use_context<T: 'static>(&self) -> &'src Rc<T> {
self.try_use_context().unwrap()
}
@ -871,7 +876,9 @@ Any function prefixed with "use" should not be called conditionally.
}
None => {
// we need to register this task
VNode::Suspended
VNode::Suspended {
real: Cell::new(RealDomNode::empty()),
}
}
}
}

View file

@ -26,6 +26,7 @@ atoms = { path="../atoms" }
async-channel = "1.6.1"
nohash-hasher = "0.2.0"
anyhow = "1.0.41"
slotmap = "1.0.3"
[dependencies.web-sys]
version = "0.3.50"

View file

@ -36,11 +36,11 @@ static Example: FC<()> = |cx| {
"Jack!"
</button>
<button
class="inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow"
onclick={move |_| set_name("jill")}>
"Jill!"
</button>
<button
class="inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow"
onclick={move |_| set_name("jill")}>
"Jill!"
</button>
</div>
</div>
</section>

View file

@ -7,6 +7,7 @@ use dioxus_core::{
};
use fxhash::FxHashMap;
use nohash_hasher::IntMap;
use slotmap::{DefaultKey, Key, KeyData};
use wasm_bindgen::{closure::Closure, JsCast};
use web_sys::{
window, Document, Element, Event, HtmlElement, HtmlInputElement, HtmlOptionElement, Node,
@ -14,7 +15,7 @@ use web_sys::{
pub struct WebsysDom {
pub stack: Stack,
nodes: IntMap<u32, Node>,
nodes: slotmap::SlotMap<DefaultKey, Node>,
document: Document,
root: Element,
@ -39,8 +40,6 @@ pub struct WebsysDom {
// `ptns` = Percy text node separator
// TODO
last_node_was_text: bool,
node_counter: Counter,
}
impl WebsysDom {
pub fn new(root: Element) -> Self {
@ -52,16 +51,18 @@ impl WebsysDom {
let (sender, mut receiver) = async_channel::unbounded::<EventTrigger>();
let sender_callback = Arc::new(move |ev| {
let mut c = sender.clone();
let c = sender.clone();
wasm_bindgen_futures::spawn_local(async move {
c.send(ev).await.unwrap();
});
});
let mut nodes =
HashMap::with_capacity_and_hasher(1000, nohash_hasher::BuildNoHashHasher::default());
let mut nodes = slotmap::SlotMap::new();
// HashMap::with_capacity_and_hasher(1000, nohash_hasher::BuildNoHashHasher::default());
// let mut nodes =
// HashMap::with_capacity_and_hasher(1000, nohash_hasher::BuildNoHashHasher::default());
nodes.insert(0_u32, root.clone().dyn_into::<Node>().unwrap());
let root_id = nodes.insert(root.clone().dyn_into::<Node>().unwrap());
Self {
stack: Stack::with_capacity(10),
nodes,
@ -74,7 +75,6 @@ impl WebsysDom {
trigger: sender_callback,
root,
last_node_was_text: false,
node_counter: Counter(0),
}
}
@ -84,17 +84,11 @@ impl WebsysDom {
}
}
struct Counter(u32);
impl Counter {
fn next(&mut self) -> u32 {
self.0 += 1;
self.0
}
}
impl dioxus_core::diff::RealDom for WebsysDom {
fn push_root(&mut self, root: dioxus_core::virtual_dom::RealDomNode) {
log::debug!("Called `[`push_root] {:?}", root);
let domnode = self.nodes.get(&root.0).expect("Failed to pop know root");
log::debug!("Called [push_root] {:?}", root);
let key: DefaultKey = KeyData::from_ffi(root.0).into();
let domnode = self.nodes.get(key).expect("Failed to pop know root");
self.stack.push(domnode.clone());
}
@ -166,15 +160,19 @@ impl dioxus_core::diff::RealDom for WebsysDom {
todo!()
}
fn create_placeholder(&mut self) -> RealDomNode {
self.create_element("pre")
}
fn create_text_node(&mut self, text: &str) -> dioxus_core::virtual_dom::RealDomNode {
let nid = self.node_counter.next();
// let nid = self.node_counter.next();
let textnode = self
.document
.create_text_node(text)
.dyn_into::<Node>()
.unwrap();
self.stack.push(textnode.clone());
self.nodes.insert(nid, textnode);
let nid = self.nodes.insert(textnode);
let nid = nid.data().as_ffi();
log::debug!("Called [`create_text_node`]: {}, {}", text, nid);
@ -190,8 +188,8 @@ impl dioxus_core::diff::RealDom for WebsysDom {
.unwrap();
self.stack.push(el.clone());
let nid = self.node_counter.next();
self.nodes.insert(nid, el);
// let nid = self.node_counter.?next();
let nid = self.nodes.insert(el).data().as_ffi();
log::debug!("Called [`create_element`]: {}, {:?}", tag, nid);
RealDomNode::new(nid)
}
@ -209,8 +207,9 @@ impl dioxus_core::diff::RealDom for WebsysDom {
.unwrap();
self.stack.push(el.clone());
let nid = self.node_counter.next();
self.nodes.insert(nid, el);
let nid = self.nodes.insert(el).data().as_ffi();
// let nid = self.node_counter.next();
// self.nodes.insert(nid, el);
log::debug!("Called [`create_element_ns`]: {:}", nid);
RealDomNode::new(nid)
}
@ -287,7 +286,7 @@ impl dioxus_core::diff::RealDom for WebsysDom {
.context("")?;
let real_id = fields
.next()
.and_then(|f| f.parse::<u32>().ok().map(RealDomNode::new))
.and_then(|f| f.parse::<u64>().ok().map(RealDomNode::new))
.context("")?;
// Call the trigger