Browse Source

Feat: listeners now have scope information

Jonathan Kelley 4 years ago
parent
commit
fcd68e6

+ 1 - 1
packages/core-macro/src/htm.rs

@@ -149,7 +149,7 @@ impl ToTokens for ToToksCtx<&Element> {
         // let ctx = self.ctx;
         let name = &self.inner.name;
         tokens.append_all(quote! {
-            dioxus::builder::#name(bump)
+            dioxus::builder::ElementBuilder::new(ctx, "#name")
         });
         for attr in self.inner.attrs.iter() {
             self.recurse(attr).to_tokens(tokens);

+ 1 - 1
packages/core-macro/src/rsxt.rs

@@ -146,7 +146,7 @@ impl ToTokens for ToToksCtx<&Element> {
         // // let ctx = self.ctx;
         let name = &self.inner.name;
         tokens.append_all(quote! {
-            dioxus::builder::#name(bump)
+            dioxus::builder::ElementBuilder::new(ctx, "#name")
         });
         for attr in self.inner.attrs.iter() {
             self.recurse(attr).to_tokens(tokens);

+ 89 - 89
packages/core/examples/alternative.rs

@@ -1,93 +1,93 @@
-//! An alternative function syntax
-//!
+// //! An alternative function syntax
+// //!
 
-use bumpalo::Bump;
-use dioxus_core::prelude::VNode;
+// use bumpalo::Bump;
+// use dioxus_core::prelude::VNode;
 
 fn main() {}
 
-struct Context2<'a, P> {
-    _props: &'a P, // _p: PhantomData<&'a ()>,
-    rops: &'a P,   // _p: PhantomData<&'a ()>,
-}
-impl<'a, P> Context2<'a, P> {
-    fn render(self, _f: impl FnOnce(&'a Bump) -> VNode<'a>) -> DTree {
-        DTree {}
-    }
-
-    fn props(&self) -> &'a P {
-        todo!()
-    }
-
-    pub fn use_hook<'scope, InternalHookState: 'static, Output: 'a>(
-        &'scope self,
-        _initializer: impl FnOnce() -> InternalHookState,
-        _runner: impl FnOnce(&'a mut InternalHookState) -> Output,
-        _cleanup: impl FnOnce(InternalHookState),
-    ) -> Output {
-        todo!()
-    }
-}
-
-trait Properties {}
-
-struct DTree;
-// type FC2<'a, T: 'a> = fn(Context2<T>) -> DTree;
-fn virtual_child<'a, T: 'a>(_bump: &'a Bump, _props: T, _f: FC2<T>) -> VNode<'a> {
-    todo!()
-}
-
-struct Props {
-    c: String,
-}
-
-fn Example(ctx: Context2<Props>) -> DTree {
-    let val = use_state(&ctx, || String::from("asd"));
-    let props = ctx.props();
-
-    ctx.render(move |b| {
-        dioxus_core::nodebuilder::div(b)
-            .child(dioxus_core::nodebuilder::text(props.c.as_str()))
-            .child(virtual_child(b, Props2 { a: val }, AltChild))
-            .finish()
-    })
-}
-
-// #[fc]
-fn Example2(ctx: Context2<()>, name: &str, _blah: &str) -> DTree {
-    let val = use_state(&ctx, || String::from("asd"));
-
-    ctx.render(move |b| {
-        dioxus_core::nodebuilder::div(b)
-            .child(dioxus_core::nodebuilder::text(name))
-            .child(virtual_child(b, Props2 { a: val }, AltChild))
-            .finish()
-    })
-}
-
-type FC2<'a, T> = fn(Context2<T>) -> DTree;
-
-// still works if you don't take any references in your props (ie, something copy or cloneable)
-static CHILD: FC2<Props2> = |_ctx: Context2<Props2>| {
-    //
-    todo!()
-};
-
-struct Props2<'a> {
-    a: &'a String,
-}
-impl Properties for Props2<'_> {}
-
-fn AltChild(ctx: Context2<Props2>) -> DTree {
-    ctx.render(|_b| {
-        //
-        todo!()
-    })
-}
-
-fn use_state<'a, 'c, P, T: 'static, F: FnOnce() -> T>(
-    _ctx: &'_ Context2<'a, P>,
-    _initial_state_fn: F,
-) -> &'a T {
-    todo!()
-}
+// struct Context2<'a, P> {
+//     _props: &'a P, // _p: PhantomData<&'a ()>,
+//     rops: &'a P,   // _p: PhantomData<&'a ()>,
+// }
+// impl<'a, P> Context2<'a, P> {
+//     fn render(self, _f: impl FnOnce(&'a Bump) -> VNode<'a>) -> DTree {
+//         DTree {}
+//     }
+
+//     fn props(&self) -> &'a P {
+//         todo!()
+//     }
+
+//     pub fn use_hook<'scope, InternalHookState: 'static, Output: 'a>(
+//         &'scope self,
+//         _initializer: impl FnOnce() -> InternalHookState,
+//         _runner: impl FnOnce(&'a mut InternalHookState) -> Output,
+//         _cleanup: impl FnOnce(InternalHookState),
+//     ) -> Output {
+//         todo!()
+//     }
+// }
+
+// trait Properties {}
+
+// struct DTree;
+// // type FC2<'a, T: 'a> = fn(Context2<T>) -> DTree;
+// fn virtual_child<'a, T: 'a>(_bump: &'a Bump, _props: T, _f: FC2<T>) -> VNode<'a> {
+//     todo!()
+// }
+
+// struct Props {
+//     c: String,
+// }
+
+// fn Example(ctx: Context2<Props>) -> DTree {
+//     let val = use_state(&ctx, || String::from("asd"));
+//     let props = ctx.props();
+
+//     ctx.render(move |b| {
+//         dioxus_core::nodebuilder::div(b)
+//             .child(dioxus_core::nodebuilder::text(props.c.as_str()))
+//             .child(virtual_child(b, Props2 { a: val }, AltChild))
+//             .finish()
+//     })
+// }
+
+// // #[fc]
+// fn Example2(ctx: Context2<()>, name: &str, _blah: &str) -> DTree {
+//     let val = use_state(&ctx, || String::from("asd"));
+
+//     ctx.render(move |ctx| {
+//         dioxus_core::builder::ElementBuilder::new(b, "div")
+//             .child(dioxus_core::nodebuilder::text(name))
+//             .child(virtual_child(b, Props2 { a: val }, AltChild))
+//             .finish()
+//     })
+// }
+
+// type FC2<'a, T> = fn(Context2<T>) -> DTree;
+
+// // still works if you don't take any references in your props (ie, something copy or cloneable)
+// static CHILD: FC2<Props2> = |_ctx: Context2<Props2>| {
+//     //
+//     todo!()
+// };
+
+// struct Props2<'a> {
+//     a: &'a String,
+// }
+// impl Properties for Props2<'_> {}
+
+// fn AltChild(ctx: Context2<Props2>) -> DTree {
+//     ctx.render(|_b| {
+//         //
+//         todo!()
+//     })
+// }
+
+// fn use_state<'a, 'c, P, T: 'static, F: FnOnce() -> T>(
+//     _ctx: &'_ Context2<'a, P>,
+//     _initial_state_fn: F,
+// ) -> &'a T {
+//     todo!()
+// }

+ 2 - 2
packages/core/examples/borrowed.rs

@@ -22,12 +22,12 @@ fn app(ctx: Context, props: &Props) -> DomTree {
     let (f, setter) = use_state(&ctx, || 0);
 
     ctx.render(move |b| {
-        let mut root = builder::div(b);
+        let mut root = builder::ElementBuilder::new(b, "div");
         for child in &props.items {
             // notice that the child directly borrows from our vec
             // this makes lists very fast (simply views reusing lifetimes)
             root = root.child(builder::virtual_child(
-                b,
+                b.bump,
                 ChildProps {
                     item: child,
                     item_handler: setter,

+ 1 - 2
packages/core/examples/contextapi.rs

@@ -1,4 +1,3 @@
-use builder::button;
 use dioxus_core::prelude::*;
 
 fn main() {}
@@ -15,7 +14,7 @@ static Example: FC<Props> = |ctx, props| {
     let value = ctx.use_context(|c: &SomeContext| c.items.last().unwrap());
 
     ctx.render(move |bump| {
-        button(bump)
+        builder::ElementBuilder::new(bump, "button")
             .on("click", move |_| {
                 println!("Value is {}", props.name);
                 println!("Value is {}", value.as_str());

+ 1 - 1
packages/core/examples/nested.rs

@@ -13,7 +13,7 @@ static Header: FC<()> = |ctx, props| {
     let handler1 = move || println!("Value is {}", inner.current());
 
     ctx.render(|bump| {
-        builder::div(bump)
+        builder::ElementBuilder::new(bump, "div")
             .child(VNode::Component(VComponent::new(
                 Bottom,
                 //

+ 589 - 0
packages/core/old/builderconstructors.rs

@@ -0,0 +1,589 @@
+// we don't want to necessarily adhere to the spec for dioxus core
+// 3rd party libs can implement their own builders if they want
+
+// macro_rules! builder_constructors {
+//     ( $(
+//         $(#[$attr:meta])*
+//         $name:ident;
+//     )* ) => {
+//         $(
+//             $(#[$attr])*
+//             #[inline]
+//             pub fn $name<'a, B>(
+//                 bump: B,
+//             ) -> ElementBuilder<
+//                 'a,
+//                 bumpalo::collections::Vec<'a, Listener<'a>>,
+//                 bumpalo::collections::Vec<'a, Attribute<'a>>,
+//                 bumpalo::collections::Vec<'a, VNode<'a>>,
+//             >
+//             where
+//                 B: Into<&'a Bump>
+//             {
+//                 ElementBuilder::new(bump, stringify!($name))
+//             }
+//         )*
+//     };
+//     ( $(
+//         $(#[$attr:meta])*
+//         $name:ident <> $namespace:tt;
+//     )* ) => {
+//         $(
+//             $(#[$attr])*
+//             #[inline]
+//             pub fn $name<'a>(
+//                 bump: &'a Bump,
+//             ) -> ElementBuilder<
+//                 'a,
+//                 bumpalo::collections::Vec<'a, Listener<'a>>,
+//                 bumpalo::collections::Vec<'a, Attribute<'a>>,
+//                 bumpalo::collections::Vec<'a, VNode<'a>>,
+//             > {
+//                 let builder = ElementBuilder::new(bump, stringify!($name));
+//                 builder.namespace(Some($namespace))
+//             }
+//         )*
+//     }
+// }
+
+// // Organized in the same order as
+// // https://developer.mozilla.org/en-US/docs/Web/HTML/Element
+// //
+// // Does not include obsolete elements.
+// builder_constructors! {
+//     // Document metadata
+
+//     /// Build a
+//     /// [`<base>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base)
+//     /// element.
+//     base;
+//     /// Build a
+//     /// [`<head>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head)
+//     /// element.
+//     head;
+//     /// Build a
+//     /// [`<link>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link)
+//     /// element.
+//     link;
+//     /// Build a
+//     /// [`<meta>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta)
+//     /// element.
+//     meta;
+//     /// Build a
+//     /// [`<style>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style)
+//     /// element.
+//     style;
+//     /// Build a
+//     /// [`<title>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title)
+//     /// element.
+//     title;
+
+//     // Sectioning root
+
+//     /// Build a
+//     /// [`<body>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/body)
+//     /// element.
+//     body;
+
+//     // Content sectioning
+
+//     /// Build a
+//     /// [`<address>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/address)
+//     /// element.
+//     address;
+//     /// Build a
+//     /// [`<article>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/article)
+//     /// element.
+//     article;
+//     /// Build a
+//     /// [`<aside>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/aside)
+//     /// element.
+//     aside;
+//     /// Build a
+//     /// [`<footer>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/footer)
+//     /// element.
+//     footer;
+//     /// Build a
+//     /// [`<header>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/header)
+//     /// element.
+//     header;
+//     /// Build a
+//     /// [`<h1>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h1)
+//     /// element.
+//     h1;
+//     /// Build a
+//     /// [`<h2>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h2)
+//     /// element.
+//     h2;
+//     /// Build a
+//     /// [`<h3>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h3)
+//     /// element.
+//     h3;
+//     /// Build a
+//     /// [`<h4>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h4)
+//     /// element.
+//     h4;
+//     /// Build a
+//     /// [`<h5>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h5)
+//     /// element.
+//     h5;
+//     /// Build a
+//     /// [`<h6>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h6)
+//     /// element.
+//     h6;
+//     /// Build a
+//     /// [`<hgroup>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hgroup)
+//     /// element.
+//     hgroup;
+//     /// Build a
+//     /// [`<main>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/main)
+//     /// element.
+//     main;
+//     /// Build a
+//     /// [`<nav>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nav)
+//     /// element.
+//     nav;
+//     /// Build a
+//     /// [`<section>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/section)
+//     /// element.
+//     section;
+
+//     // Text content
+
+//     /// Build a
+//     /// [`<blockquote>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote)
+//     /// element.
+//     blockquote;
+//     /// Build a
+//     /// [`<dd>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dd)
+//     /// element.
+//     dd;
+//     /// Build a
+//     /// [`<div>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div)
+//     /// element.
+//     div;
+//     /// Build a
+//     /// [`<dl>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl)
+//     /// element.
+//     dl;
+//     /// Build a
+//     /// [`<dt>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dt)
+//     /// element.
+//     dt;
+//     /// Build a
+//     /// [`<figcaption>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figcaption)
+//     /// element.
+//     figcaption;
+//     /// Build a
+//     /// [`<figure>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure)
+//     /// element.
+//     figure;
+//     /// Build a
+//     /// [`<hr>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hr)
+//     /// element.
+//     hr;
+//     /// Build a
+//     /// [`<li>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/li)
+//     /// element.
+//     li;
+//     /// Build a
+//     /// [`<ol>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ol)
+//     /// element.
+//     ol;
+//     /// Build a
+//     /// [`<p>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/p)
+//     /// element.
+//     p;
+//     /// Build a
+//     /// [`<pre>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre)
+//     /// element.
+//     pre;
+//     /// Build a
+//     /// [`<ul>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul)
+//     /// element.
+//     ul;
+
+//     // Inline text semantics
+
+//     /// Build a
+//     /// [`<a>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a)
+//     /// element.
+//     a;
+//     /// Build a
+//     /// [`<abbr>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/abbr)
+//     /// element.
+//     abbr;
+//     /// Build a
+//     /// [`<b>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/b)
+//     /// element.
+//     b;
+//     /// Build a
+//     /// [`<bdi>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/bdi)
+//     /// element.
+//     bdi;
+//     /// Build a
+//     /// [`<bdo>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/bdo)
+//     /// element.
+//     bdo;
+//     /// Build a
+//     /// [`<br>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/br)
+//     /// element.
+//     br;
+//     /// Build a
+//     /// [`<cite>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/cite)
+//     /// element.
+//     cite;
+//     /// Build a
+//     /// [`<code>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/code)
+//     /// element.
+//     code;
+//     /// Build a
+//     /// [`<data>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/data)
+//     /// element.
+//     data;
+//     /// Build a
+//     /// [`<dfn>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dfn)
+//     /// element.
+//     dfn;
+//     /// Build a
+//     /// [`<em>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/em)
+//     /// element.
+//     em;
+//     /// Build a
+//     /// [`<i>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/i)
+//     /// element.
+//     i;
+//     /// Build a
+//     /// [`<kbd>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/kbd)
+//     /// element.
+//     kbd;
+//     /// Build a
+//     /// [`<mark>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark)
+//     /// element.
+//     mark;
+//     /// Build a
+//     /// [`<q>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q)
+//     /// element.
+//     q;
+//     /// Build a
+//     /// [`<rb>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rb)
+//     /// element.
+//     rb;
+//     /// Build a
+//     /// [`<rp>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rp)
+//     /// element.
+//     rp;
+//     /// Build a
+//     /// [`<rt>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rt)
+//     /// element.
+//     rt;
+//     /// Build a
+//     /// [`<rtc>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rtc)
+//     /// element.
+//     rtc;
+//     /// Build a
+//     /// [`<ruby>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ruby)
+//     /// element.
+//     ruby;
+//     /// Build a
+//     /// [`<s>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/s)
+//     /// element.
+//     s;
+//     /// Build a
+//     /// [`<samp>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/samp)
+//     /// element.
+//     samp;
+//     /// Build a
+//     /// [`<small>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/small)
+//     /// element.
+//     small;
+//     /// Build a
+//     /// [`<span>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/span)
+//     /// element.
+//     span;
+//     /// Build a
+//     /// [`<strong>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/strong)
+//     /// element.
+//     strong;
+//     /// Build a
+//     /// [`<sub>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sub)
+//     /// element.
+//     sub;
+//     /// Build a
+//     /// [`<sup>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sup)
+//     /// element.
+//     sup;
+//     /// Build a
+//     /// [`<time>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time)
+//     /// element.
+//     time;
+//     /// Build a
+//     /// [`<u>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/u)
+//     /// element.
+//     u;
+//     /// Build a
+//     /// [`<var>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/var)
+//     /// element.
+//     var;
+//     /// Build a
+//     /// [`<wbr>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr)
+//     /// element.
+//     wbr;
+
+//     // Image and multimedia
+
+//     /// Build a
+//     /// [`<area>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/area)
+//     /// element.
+//     area;
+//     /// Build a
+//     /// [`<audio>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio)
+//     /// element.
+//     audio;
+//     /// Build a
+//     /// [`<img>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img)
+//     /// element.
+//     img;
+//     /// Build a
+//     /// [`<map>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/map)
+//     /// element.
+//     map;
+//     /// Build a
+//     /// [`<track>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/track)
+//     /// element.
+//     track;
+//     /// Build a
+//     /// [`<video>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video)
+//     /// element.
+//     video;
+
+//     // Embedded content
+
+//     /// Build a
+//     /// [`<embed>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/embed)
+//     /// element.
+//     embed;
+//     /// Build a
+//     /// [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe)
+//     /// element.
+//     iframe;
+//     /// Build a
+//     /// [`<object>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object)
+//     /// element.
+//     object;
+//     /// Build a
+//     /// [`<param>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/param)
+//     /// element.
+//     param;
+//     /// Build a
+//     /// [`<picture>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture)
+//     /// element.
+//     picture;
+//     /// Build a
+//     /// [`<source>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source)
+//     /// element.
+//     source;
+
+//     // Scripting
+
+//     /// Build a
+//     /// [`<canvas>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas)
+//     /// element.
+//     canvas;
+//     /// Build a
+//     /// [`<noscript>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/noscript)
+//     /// element.
+//     noscript;
+//     /// Build a
+//     /// [`<script>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)
+//     /// element.
+//     script;
+
+//     // Demarcating edits
+
+//     /// Build a
+//     /// [`<del>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/del)
+//     /// element.
+//     del;
+//     /// Build a
+//     /// [`<ins>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ins)
+//     /// element.
+//     ins;
+
+//     // Table content
+
+//     /// Build a
+//     /// [`<caption>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption)
+//     /// element.
+//     caption;
+//     /// Build a
+//     /// [`<col>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/col)
+//     /// element.
+//     col;
+//     /// Build a
+//     /// [`<colgroup>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/colgroup)
+//     /// element.
+//     colgroup;
+//     /// Build a
+//     /// [`<table>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table)
+//     /// element.
+//     table;
+//     /// Build a
+//     /// [`<tbody>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tbody)
+//     /// element.
+//     tbody;
+//     /// Build a
+//     /// [`<td>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td)
+//     /// element.
+//     td;
+//     /// Build a
+//     /// [`<tfoot>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tfoot)
+//     /// element.
+//     tfoot;
+//     /// Build a
+//     /// [`<th>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/th)
+//     /// element.
+//     th;
+//     /// Build a
+//     /// [`<thead>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/thead)
+//     /// element.
+//     thead;
+//     /// Build a
+//     /// [`<tr>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tr)
+//     /// element.
+//     tr;
+
+//     // Forms
+
+//     /// Build a
+//     /// [`<button>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button)
+//     /// element.
+//     button;
+//     /// Build a
+//     /// [`<datalist>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist)
+//     /// element.
+//     datalist;
+//     /// Build a
+//     /// [`<fieldset>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset)
+//     /// element.
+//     fieldset;
+//     /// Build a
+//     /// [`<form>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form)
+//     /// element.
+//     form;
+//     /// Build a
+//     /// [`<input>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input)
+//     /// element.
+//     input;
+//     /// Build a
+//     /// [`<label>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label)
+//     /// element.
+//     label;
+//     /// Build a
+//     /// [`<legend>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/legend)
+//     /// element.
+//     legend;
+//     /// Build a
+//     /// [`<meter>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meter)
+//     /// element.
+//     meter;
+//     /// Build a
+//     /// [`<optgroup>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup)
+//     /// element.
+//     optgroup;
+//     /// Build a
+//     /// [`<option>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option)
+//     /// element.
+//     option;
+//     /// Build a
+//     /// [`<output>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/output)
+//     /// element.
+//     output;
+//     /// Build a
+//     /// [`<progress>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress)
+//     /// element.
+//     progress;
+//     /// Build a
+//     /// [`<select>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select)
+//     /// element.
+//     select;
+//     /// Build a
+//     /// [`<textarea>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea)
+//     /// element.
+//     textarea;
+
+//     // Interactive elements
+
+//     /// Build a
+//     /// [`<details>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details)
+//     /// element.
+//     details;
+//     /// Build a
+//     /// [`<dialog>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog)
+//     /// element.
+//     dialog;
+//     /// Build a
+//     /// [`<menu>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menu)
+//     /// element.
+//     menu;
+//     /// Build a
+//     /// [`<menuitem>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menuitem)
+//     /// element.
+//     menuitem;
+//     /// Build a
+//     /// [`<summary>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary)
+//     /// element.
+//     summary;
+
+//     // Web components
+
+//     /// Build a
+//     /// [`<slot>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot)
+//     /// element.
+//     slot;
+//     /// Build a
+//     /// [`<template>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template)
+//     /// element.
+//     template;
+// }
+
+// builder_constructors! {
+//     // SVG components
+
+//     /// Build a
+//     /// [`<svg>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg)
+//     /// element.
+//     svg <> "http://www.w3.org/2000/svg" ;
+//     /// Build a
+//     /// [`<path>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path)
+//     /// element.
+//     path <> "http://www.w3.org/2000/svg";
+//     /// Build a
+//     /// [`<circle>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/circle)
+//     /// element.
+//     circle <>  "http://www.w3.org/2000/svg";
+//     /// Build a
+//     /// [`<ellipse>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/ellipse)
+//     /// element.
+//     ellipse <> "http://www.w3.org/2000/svg";
+//     /// Build a
+//     /// [`<line>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/line)
+//     /// element.
+//     line <> "http://www.w3.org/2000/svg";
+//     /// Build a
+//     /// [`<polygon>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/polygon)
+//     /// element.
+//     polygon <> "http://www.w3.org/2000/svg";
+//     /// Build a
+//     /// [`<polyline>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/polyline)
+//     /// element.
+//     polyline <> "http://www.w3.org/2000/svg";
+//     /// Build a
+//     /// [`<rect>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/rect)
+//     /// element.
+//     rect <> "http://www.w3.org/2000/svg";
+//     /// Build a
+//     /// [`<image>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/image)
+//     /// element.
+//     image <> "http://www.w3.org/2000/svg";
+// }

+ 1 - 0
packages/core/src/component.rs

@@ -48,6 +48,7 @@ mod tests {
 
         ctx.render(html! {
             <div>
+
             </div>
         })
     };

+ 17 - 7
packages/core/src/context.rs

@@ -31,6 +31,8 @@ use std::{
 pub struct Context<'src> {
     pub idx: AtomicUsize,
 
+    pub scope: ScopeIdx,
+
     // Borrowed from scope
     pub(crate) arena: &'src typed_arena::Arena<Hook>,
     pub(crate) hooks: &'src RefCell<Vec<*mut Hook>>,
@@ -76,12 +78,17 @@ impl<'a> Context<'a> {
     ///     ctx.render(lazy_tree)
     /// }
     ///```
-    pub fn render(self, lazy_nodes: impl FnOnce(NodeCtx<'a>) -> VNode<'a> + 'a) -> DomTree {
-        let ctx = NodeCtx { bump: self.bump };
-        let safe_nodes = lazy_nodes(ctx);
-
-        let unsafe_nodes = unsafe { std::mem::transmute::<VNode<'a>, VNode<'static>>(safe_nodes) };
-        self.final_nodes.deref().borrow_mut().replace(unsafe_nodes);
+    pub fn render(self, lazy_nodes: impl FnOnce(&'a NodeCtx<'a>) -> VNode<'a> + 'a) -> DomTree {
+        let ctx = NodeCtx {
+            bump: self.bump,
+            idx: 0.into(),
+            scope: self.scope,
+        };
+        todo!();
+        // let safe_nodes = lazy_nodes(&ctx);
+
+        // let unsafe_nodes = unsafe { std::mem::transmute::<VNode<'a>, VNode<'static>>(safe_nodes) };
+        // self.final_nodes.deref().borrow_mut().replace(unsafe_nodes);
         DomTree {}
     }
 
@@ -100,8 +107,11 @@ impl<'a> Context<'a> {
 
 // NodeCtx is used to build VNodes in the component's memory space.
 // This struct adds metadata to the final DomTree about listeners, attributes, and children
+#[derive(Debug, Clone)]
 pub struct NodeCtx<'a> {
-    bump: &'a Bump,
+    pub bump: &'a Bump,
+    pub idx: RefCell<usize>,
+    pub scope: ScopeIdx,
 }
 
 impl NodeCtx<'_> {

+ 20 - 97
packages/core/src/diff.rs

@@ -78,12 +78,6 @@ impl<'a> DiffMachine<'a> {
         new: &VNode<'a>,
         // scope: Option<generational_arena::Index>,
     ) {
-        log::debug!("old {:#?}", old);
-        log::debug!("new {:#?}", new);
-
-        // Set it while diffing
-        // Reset it when finished diffing
-        // self.current_idx = scope;
         /*
         For each valid case, we "commit traversal", meaning we save this current position in the tree.
         Then, we diff and queue an edit event (via chagelist). s single trees - when components show up, we save that traversal and then re-enter later.
@@ -98,7 +92,6 @@ impl<'a> DiffMachine<'a> {
                 }
             }
 
-            // Definitely different, need to commit update
             (VNode::Text(_), VNode::Element(_)) => {
                 // TODO: Hook up the events properly
                 // todo!("Hook up events registry");
@@ -109,112 +102,37 @@ impl<'a> DiffMachine<'a> {
                 self.change_list.replace_with();
             }
 
-            // Definitely different, need to commit update
             (VNode::Element(_), VNode::Text(_)) => {
                 self.change_list.commit_traversal();
                 self.create(new);
-
-                // create(cached_set, self.change_list, registry, new, cached_roots);
-                // Note: text nodes cannot have event listeners, so we don't need to
-                // remove the old node's listeners from our registry her.
                 self.change_list.replace_with();
             }
-            // compare elements
-            // if different, schedule different types of update
+
             (VNode::Element(eold), VNode::Element(enew)) => {
-                // log::debug!("elements are different");
                 // If the element type is completely different, the element needs to be re-rendered completely
                 if enew.tag_name != eold.tag_name || enew.namespace != eold.namespace {
                     self.change_list.commit_traversal();
-                    // create(cached_set, self.change_list, registry, new, cached_roots);
-                    // registry.remove_subtree(&old);
                     self.change_list.replace_with();
                     return;
                 }
 
                 self.diff_listeners(eold.listeners, enew.listeners);
-
                 self.diff_attr(eold.attributes, enew.attributes, enew.namespace.is_some());
-
                 self.diff_children(eold.children, enew.children);
             }
-            // No immediate change to dom. If props changed though, queue a "props changed" update
-            // However, mark these for a
+
             (VNode::Component(_), VNode::Component(_)) => {
                 todo!("Usage of component VNode not currently supported");
-                //     // Both the new and old nodes are cached.
-                //     (&NodeKind::Cached(ref new), &NodeKind::Cached(ref old)) => {
-                //         cached_roots.insert(new.id);
-                //         if new.id == old.id {
-                //             // This is the same cached node, so nothing has changed!
-                //             return;
-                //         }
-                //         let (new, new_template) = cached_set.get(new.id);
-                //         let (old, old_template) = cached_set.get(old.id);
-                //         if new_template == old_template {
-                //             // If they are both using the same template, then just diff the
-                //             // subtrees.
-                //             diff(cached_set, change_list, registry, old, new, cached_roots);
-                //         } else {
-                //             // Otherwise, they are probably different enough that
-                //             // re-constructing the subtree from scratch should be faster.
-                //             // This doubly holds true if we have a new template.
-                //             change_list.commit_traversal();
-                //             create_and_replace(
-                //                 cached_set,
-                //                 change_list,
-                //                 registry,
-                //                 new_template,
-                //                 old,
-                //                 new,
-                //                 cached_roots,
-                //             );
-                //         }
-                //     }
-                // queue a lifecycle event.
-                // no change
             }
 
-            // A component has been birthed!
-            // Queue its arrival
             (_, VNode::Component(_)) => {
                 todo!("Usage of component VNode not currently supported");
-                //     // Old cached node and new non-cached node. Again, assume that they are
-                //     // probably pretty different and create the new non-cached node afresh.
-                //     (_, &NodeKind::Cached(_)) => {
-                //         change_list.commit_traversal();
-                //         create(cached_set, change_list, registry, new, cached_roots);
-                //         registry.remove_subtree(&old);
-                //         change_list.replace_with();
-                //     }
-                // }
             }
 
-            // A component was removed :(
-            // Queue its removal
             (VNode::Component(_), _) => {
-                //     // New cached node when the old node was not cached. In this scenario,
-                //     // we assume that they are pretty different, and it isn't worth diffing
-                //     // the subtrees, so we just create the new cached node afresh.
-                //     (&NodeKind::Cached(ref c), _) => {
-                //         change_list.commit_traversal();
-                //         cached_roots.insert(c.id);
-                //         let (new, new_template) = cached_set.get(c.id);
-                //         create_and_replace(
-                //             cached_set,
-                //             change_list,
-                //             registry,
-                //             new_template,
-                //             old,
-                //             new,
-                //             cached_roots,
-                //         );
-                //     }
                 todo!("Usage of component VNode not currently supported");
             }
 
-            // A suspended component appeared!
-            // Don't do much, just wait
             (VNode::Suspended, _) | (_, VNode::Suspended) => {
                 // (VNode::Element(_), VNode::Suspended) => {}
                 // (VNode::Text(_), VNode::Suspended) => {}
@@ -254,17 +172,19 @@ impl<'a> DiffMachine<'a> {
                 if new_l.event == old_l.event {
                     // if let Some(scope) = self.current_idx {
                     //     let cb = CbIdx::from_gi_index(scope, l_idx);
-                    self.change_list.update_event_listener(event_type, cb);
+                    self.change_list
+                        .update_event_listener(event_type, new_l.scope, new_l.id);
                     // }
 
                     continue 'outer1;
                 }
             }
 
-            if let Some(scope) = self.current_idx {
-                let cb = CbIdx::from_gi_index(scope, l_idx);
-                self.change_list.new_event_listener(event_type, cb);
-            }
+            // if let Some(scope) = self.current_idx {
+            // let cb = CbIdx::from_gi_index(scope, l_idx);
+            self.change_list
+                .new_event_listener(event_type, new_l.scope, new_l.id);
+            // }
         }
 
         'outer2: for old_l in old {
@@ -893,14 +813,17 @@ impl<'a> DiffMachine<'a> {
                 }
 
                 listeners.iter().enumerate().for_each(|(id, listener)| {
-                    if let Some(index) = self.current_idx {
-                        self.change_list
-                            .new_event_listener(listener.event, CbIdx::from_gi_index(index, id));
-                    } else {
-                        // Don't panic
-                        // Used for testing
-                        log::trace!("Failed to set listener, create was not called in the context of the virtual dom");
-                    }
+                    // if let Some(index) = self.current_idx {
+                    self.change_list.new_event_listener(
+                        listener.event,
+                        listener.scope,
+                        listener.id,
+                    );
+                    // } else {
+                    // Don't panic
+                    // Used for testing
+                    //     log::trace!("Failed to set listener, create was not called in the context of the virtual dom");
+                    // }
                 });
                 // for l in listeners {
                 // unsafe {

+ 51 - 631
packages/core/src/nodebuilder.rs

@@ -3,6 +3,7 @@
 use std::ops::Deref;
 
 use crate::{
+    context::NodeCtx,
     events::VirtualEvent,
     innerlude::VComponent,
     nodes::{Attribute, Listener, NodeKey, VNode},
@@ -17,14 +18,14 @@ use bumpalo::Bump;
 /// Typically constructed with element-specific constructors, eg the `div`
 /// function for building `<div>` elements or the `button` function for building
 /// `<button>` elements.
-#[derive(Clone, Debug)]
+#[derive(Debug)]
 pub struct ElementBuilder<'a, Listeners, Attributes, Children>
 where
     Listeners: 'a + AsRef<[Listener<'a>]>,
     Attributes: 'a + AsRef<[Attribute<'a>]>,
     Children: 'a + AsRef<[VNode<'a>]>,
 {
-    bump: &'a Bump,
+    ctx: &'a NodeCtx<'a>,
     key: NodeKey,
     tag_name: &'a str,
     listeners: Listeners,
@@ -64,13 +65,11 @@ impl<'a>
     /// let my_element_builder = ElementBuilder::new(&b, tag_name);
     /// # fn flip_coin() -> bool { true }
     /// ```
-    pub fn new<B>(bump: B, tag_name: &'a str) -> Self
-    where
-        B: Into<&'a Bump>,
-    {
-        let bump = bump.into();
+    pub fn new(ctx: &'a NodeCtx<'a>, tag_name: &'static str) -> Self {
+        // pub fn new<B>(ctx: &'a mut NodeCtx<'a>, tag_name: &'a str) -> Self {
+        let bump = ctx.bump();
         ElementBuilder {
-            bump,
+            ctx,
             key: NodeKey::NONE,
             tag_name,
             listeners: bumpalo::collections::Vec::new_in(bump),
@@ -120,7 +119,7 @@ where
         L: 'a + AsRef<[Listener<'a>]>,
     {
         ElementBuilder {
-            bump: self.bump,
+            ctx: self.ctx,
             key: self.key,
             tag_name: self.tag_name,
             listeners,
@@ -159,7 +158,7 @@ where
         A: 'a + AsRef<[Attribute<'a>]>,
     {
         ElementBuilder {
-            bump: self.bump,
+            ctx: self.ctx,
             key: self.key,
             tag_name: self.tag_name,
             listeners: self.listeners,
@@ -198,7 +197,7 @@ where
         C: 'a + AsRef<[VNode<'a>]>,
     {
         ElementBuilder {
-            bump: self.bump,
+            ctx: self.ctx,
             key: self.key,
             tag_name: self.tag_name,
             listeners: self.listeners,
@@ -225,7 +224,7 @@ where
     #[inline]
     pub fn namespace(self, namespace: Option<&'a str>) -> Self {
         ElementBuilder {
-            bump: self.bump,
+            ctx: self.ctx,
             key: self.key,
             tag_name: self.tag_name,
             listeners: self.listeners,
@@ -291,17 +290,17 @@ where
     /// ```
     #[inline]
     pub fn finish(self) -> VNode<'a> {
-        let children: &'a Children = self.bump.alloc(self.children);
+        let children: &'a Children = self.ctx.bump().alloc(self.children);
         let children: &'a [VNode<'a>] = children.as_ref();
 
-        let listeners: &'a Listeners = self.bump.alloc(self.listeners);
+        let listeners: &'a Listeners = self.ctx.bump().alloc(self.listeners);
         let listeners: &'a [Listener<'a>] = listeners.as_ref();
 
-        let attributes: &'a Attributes = self.bump.alloc(self.attributes);
+        let attributes: &'a Attributes = self.ctx.bump().alloc(self.attributes);
         let attributes: &'a [Attribute<'a>] = attributes.as_ref();
 
         VNode::element(
-            self.bump,
+            self.ctx.bump(),
             self.key,
             self.tag_name,
             listeners,
@@ -340,10 +339,18 @@ where
     /// ```
     #[inline]
     pub fn on(mut self, event: &'static str, callback: impl Fn(VirtualEvent) + 'a) -> Self {
+        // todo:
+        // increment listner id from nodectx ref
+        // add listener attrs here instead of later?
         self.listeners.push(Listener {
             event,
-            callback: self.bump.alloc(callback),
+            callback: self.ctx.bump.alloc(callback),
+            id: *self.ctx.idx.borrow(),
+            scope: self.ctx.scope,
         });
+
+        // bump the context id forward
+        *self.ctx.idx.borrow_mut() += 1;
         self
     }
 }
@@ -435,593 +442,6 @@ where
     }
 }
 
-macro_rules! builder_constructors {
-    ( $(
-        $(#[$attr:meta])*
-        $name:ident;
-    )* ) => {
-        $(
-            $(#[$attr])*
-            #[inline]
-            pub fn $name<'a, B>(
-                bump: B,
-            ) -> ElementBuilder<
-                'a,
-                bumpalo::collections::Vec<'a, Listener<'a>>,
-                bumpalo::collections::Vec<'a, Attribute<'a>>,
-                bumpalo::collections::Vec<'a, VNode<'a>>,
-            >
-            where
-                B: Into<&'a Bump>
-            {
-                ElementBuilder::new(bump, stringify!($name))
-            }
-        )*
-    };
-    ( $(
-        $(#[$attr:meta])*
-        $name:ident <> $namespace:tt;
-    )* ) => {
-        $(
-            $(#[$attr])*
-            #[inline]
-            pub fn $name<'a>(
-                bump: &'a Bump,
-            ) -> ElementBuilder<
-                'a,
-                bumpalo::collections::Vec<'a, Listener<'a>>,
-                bumpalo::collections::Vec<'a, Attribute<'a>>,
-                bumpalo::collections::Vec<'a, VNode<'a>>,
-            > {
-                let builder = ElementBuilder::new(bump, stringify!($name));
-                builder.namespace(Some($namespace))
-            }
-        )*
-    }
-}
-
-// Organized in the same order as
-// https://developer.mozilla.org/en-US/docs/Web/HTML/Element
-//
-// Does not include obsolete elements.
-builder_constructors! {
-    // Document metadata
-
-    /// Build a
-    /// [`<base>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base)
-    /// element.
-    base;
-    /// Build a
-    /// [`<head>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/head)
-    /// element.
-    head;
-    /// Build a
-    /// [`<link>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/link)
-    /// element.
-    link;
-    /// Build a
-    /// [`<meta>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta)
-    /// element.
-    meta;
-    /// Build a
-    /// [`<style>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style)
-    /// element.
-    style;
-    /// Build a
-    /// [`<title>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/title)
-    /// element.
-    title;
-
-    // Sectioning root
-
-    /// Build a
-    /// [`<body>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/body)
-    /// element.
-    body;
-
-    // Content sectioning
-
-    /// Build a
-    /// [`<address>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/address)
-    /// element.
-    address;
-    /// Build a
-    /// [`<article>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/article)
-    /// element.
-    article;
-    /// Build a
-    /// [`<aside>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/aside)
-    /// element.
-    aside;
-    /// Build a
-    /// [`<footer>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/footer)
-    /// element.
-    footer;
-    /// Build a
-    /// [`<header>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/header)
-    /// element.
-    header;
-    /// Build a
-    /// [`<h1>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h1)
-    /// element.
-    h1;
-    /// Build a
-    /// [`<h2>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h2)
-    /// element.
-    h2;
-    /// Build a
-    /// [`<h3>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h3)
-    /// element.
-    h3;
-    /// Build a
-    /// [`<h4>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h4)
-    /// element.
-    h4;
-    /// Build a
-    /// [`<h5>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h5)
-    /// element.
-    h5;
-    /// Build a
-    /// [`<h6>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/h6)
-    /// element.
-    h6;
-    /// Build a
-    /// [`<hgroup>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hgroup)
-    /// element.
-    hgroup;
-    /// Build a
-    /// [`<main>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/main)
-    /// element.
-    main;
-    /// Build a
-    /// [`<nav>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/nav)
-    /// element.
-    nav;
-    /// Build a
-    /// [`<section>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/section)
-    /// element.
-    section;
-
-    // Text content
-
-    /// Build a
-    /// [`<blockquote>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote)
-    /// element.
-    blockquote;
-    /// Build a
-    /// [`<dd>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dd)
-    /// element.
-    dd;
-    /// Build a
-    /// [`<div>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/div)
-    /// element.
-    div;
-    /// Build a
-    /// [`<dl>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dl)
-    /// element.
-    dl;
-    /// Build a
-    /// [`<dt>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dt)
-    /// element.
-    dt;
-    /// Build a
-    /// [`<figcaption>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figcaption)
-    /// element.
-    figcaption;
-    /// Build a
-    /// [`<figure>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/figure)
-    /// element.
-    figure;
-    /// Build a
-    /// [`<hr>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/hr)
-    /// element.
-    hr;
-    /// Build a
-    /// [`<li>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/li)
-    /// element.
-    li;
-    /// Build a
-    /// [`<ol>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ol)
-    /// element.
-    ol;
-    /// Build a
-    /// [`<p>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/p)
-    /// element.
-    p;
-    /// Build a
-    /// [`<pre>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/pre)
-    /// element.
-    pre;
-    /// Build a
-    /// [`<ul>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ul)
-    /// element.
-    ul;
-
-    // Inline text semantics
-
-    /// Build a
-    /// [`<a>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a)
-    /// element.
-    a;
-    /// Build a
-    /// [`<abbr>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/abbr)
-    /// element.
-    abbr;
-    /// Build a
-    /// [`<b>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/b)
-    /// element.
-    b;
-    /// Build a
-    /// [`<bdi>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/bdi)
-    /// element.
-    bdi;
-    /// Build a
-    /// [`<bdo>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/bdo)
-    /// element.
-    bdo;
-    /// Build a
-    /// [`<br>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/br)
-    /// element.
-    br;
-    /// Build a
-    /// [`<cite>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/cite)
-    /// element.
-    cite;
-    /// Build a
-    /// [`<code>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/code)
-    /// element.
-    code;
-    /// Build a
-    /// [`<data>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/data)
-    /// element.
-    data;
-    /// Build a
-    /// [`<dfn>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dfn)
-    /// element.
-    dfn;
-    /// Build a
-    /// [`<em>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/em)
-    /// element.
-    em;
-    /// Build a
-    /// [`<i>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/i)
-    /// element.
-    i;
-    /// Build a
-    /// [`<kbd>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/kbd)
-    /// element.
-    kbd;
-    /// Build a
-    /// [`<mark>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/mark)
-    /// element.
-    mark;
-    /// Build a
-    /// [`<q>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/q)
-    /// element.
-    q;
-    /// Build a
-    /// [`<rb>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rb)
-    /// element.
-    rb;
-    /// Build a
-    /// [`<rp>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rp)
-    /// element.
-    rp;
-    /// Build a
-    /// [`<rt>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rt)
-    /// element.
-    rt;
-    /// Build a
-    /// [`<rtc>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/rtc)
-    /// element.
-    rtc;
-    /// Build a
-    /// [`<ruby>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ruby)
-    /// element.
-    ruby;
-    /// Build a
-    /// [`<s>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/s)
-    /// element.
-    s;
-    /// Build a
-    /// [`<samp>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/samp)
-    /// element.
-    samp;
-    /// Build a
-    /// [`<small>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/small)
-    /// element.
-    small;
-    /// Build a
-    /// [`<span>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/span)
-    /// element.
-    span;
-    /// Build a
-    /// [`<strong>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/strong)
-    /// element.
-    strong;
-    /// Build a
-    /// [`<sub>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sub)
-    /// element.
-    sub;
-    /// Build a
-    /// [`<sup>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sup)
-    /// element.
-    sup;
-    /// Build a
-    /// [`<time>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time)
-    /// element.
-    time;
-    /// Build a
-    /// [`<u>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/u)
-    /// element.
-    u;
-    /// Build a
-    /// [`<var>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/var)
-    /// element.
-    var;
-    /// Build a
-    /// [`<wbr>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/wbr)
-    /// element.
-    wbr;
-
-    // Image and multimedia
-
-    /// Build a
-    /// [`<area>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/area)
-    /// element.
-    area;
-    /// Build a
-    /// [`<audio>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio)
-    /// element.
-    audio;
-    /// Build a
-    /// [`<img>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img)
-    /// element.
-    img;
-    /// Build a
-    /// [`<map>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/map)
-    /// element.
-    map;
-    /// Build a
-    /// [`<track>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/track)
-    /// element.
-    track;
-    /// Build a
-    /// [`<video>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video)
-    /// element.
-    video;
-
-    // Embedded content
-
-    /// Build a
-    /// [`<embed>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/embed)
-    /// element.
-    embed;
-    /// Build a
-    /// [`<iframe>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe)
-    /// element.
-    iframe;
-    /// Build a
-    /// [`<object>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/object)
-    /// element.
-    object;
-    /// Build a
-    /// [`<param>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/param)
-    /// element.
-    param;
-    /// Build a
-    /// [`<picture>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/picture)
-    /// element.
-    picture;
-    /// Build a
-    /// [`<source>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/source)
-    /// element.
-    source;
-
-    // Scripting
-
-    /// Build a
-    /// [`<canvas>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas)
-    /// element.
-    canvas;
-    /// Build a
-    /// [`<noscript>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/noscript)
-    /// element.
-    noscript;
-    /// Build a
-    /// [`<script>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script)
-    /// element.
-    script;
-
-    // Demarcating edits
-
-    /// Build a
-    /// [`<del>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/del)
-    /// element.
-    del;
-    /// Build a
-    /// [`<ins>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/ins)
-    /// element.
-    ins;
-
-    // Table content
-
-    /// Build a
-    /// [`<caption>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption)
-    /// element.
-    caption;
-    /// Build a
-    /// [`<col>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/col)
-    /// element.
-    col;
-    /// Build a
-    /// [`<colgroup>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/colgroup)
-    /// element.
-    colgroup;
-    /// Build a
-    /// [`<table>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/table)
-    /// element.
-    table;
-    /// Build a
-    /// [`<tbody>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tbody)
-    /// element.
-    tbody;
-    /// Build a
-    /// [`<td>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td)
-    /// element.
-    td;
-    /// Build a
-    /// [`<tfoot>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tfoot)
-    /// element.
-    tfoot;
-    /// Build a
-    /// [`<th>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/th)
-    /// element.
-    th;
-    /// Build a
-    /// [`<thead>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/thead)
-    /// element.
-    thead;
-    /// Build a
-    /// [`<tr>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/tr)
-    /// element.
-    tr;
-
-    // Forms
-
-    /// Build a
-    /// [`<button>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button)
-    /// element.
-    button;
-    /// Build a
-    /// [`<datalist>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist)
-    /// element.
-    datalist;
-    /// Build a
-    /// [`<fieldset>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fieldset)
-    /// element.
-    fieldset;
-    /// Build a
-    /// [`<form>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form)
-    /// element.
-    form;
-    /// Build a
-    /// [`<input>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input)
-    /// element.
-    input;
-    /// Build a
-    /// [`<label>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label)
-    /// element.
-    label;
-    /// Build a
-    /// [`<legend>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/legend)
-    /// element.
-    legend;
-    /// Build a
-    /// [`<meter>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meter)
-    /// element.
-    meter;
-    /// Build a
-    /// [`<optgroup>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/optgroup)
-    /// element.
-    optgroup;
-    /// Build a
-    /// [`<option>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option)
-    /// element.
-    option;
-    /// Build a
-    /// [`<output>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/output)
-    /// element.
-    output;
-    /// Build a
-    /// [`<progress>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress)
-    /// element.
-    progress;
-    /// Build a
-    /// [`<select>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select)
-    /// element.
-    select;
-    /// Build a
-    /// [`<textarea>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea)
-    /// element.
-    textarea;
-
-    // Interactive elements
-
-    /// Build a
-    /// [`<details>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details)
-    /// element.
-    details;
-    /// Build a
-    /// [`<dialog>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog)
-    /// element.
-    dialog;
-    /// Build a
-    /// [`<menu>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menu)
-    /// element.
-    menu;
-    /// Build a
-    /// [`<menuitem>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/menuitem)
-    /// element.
-    menuitem;
-    /// Build a
-    /// [`<summary>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/summary)
-    /// element.
-    summary;
-
-    // Web components
-
-    /// Build a
-    /// [`<slot>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot)
-    /// element.
-    slot;
-    /// Build a
-    /// [`<template>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template)
-    /// element.
-    template;
-}
-
-builder_constructors! {
-    // SVG components
-
-    /// Build a
-    /// [`<svg>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg)
-    /// element.
-    svg <> "http://www.w3.org/2000/svg" ;
-    /// Build a
-    /// [`<path>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/path)
-    /// element.
-    path <> "http://www.w3.org/2000/svg";
-    /// Build a
-    /// [`<circle>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/circle)
-    /// element.
-    circle <>  "http://www.w3.org/2000/svg";
-    /// Build a
-    /// [`<ellipse>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/ellipse)
-    /// element.
-    ellipse <> "http://www.w3.org/2000/svg";
-    /// Build a
-    /// [`<line>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/line)
-    /// element.
-    line <> "http://www.w3.org/2000/svg";
-    /// Build a
-    /// [`<polygon>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/polygon)
-    /// element.
-    polygon <> "http://www.w3.org/2000/svg";
-    /// Build a
-    /// [`<polyline>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/polyline)
-    /// element.
-    polyline <> "http://www.w3.org/2000/svg";
-    /// Build a
-    /// [`<rect>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/rect)
-    /// element.
-    rect <> "http://www.w3.org/2000/svg";
-    /// Build a
-    /// [`<image>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/image)
-    /// element.
-    image <> "http://www.w3.org/2000/svg";
-}
-
 /// Construct a text VNode.
 ///
 /// This is `dioxus`'s virtual DOM equivalent of `document.createTextVNode`.
@@ -1062,33 +482,33 @@ pub fn attr<'a>(name: &'static str, value: &'a str) -> Attribute<'a> {
     Attribute { name, value }
 }
 
-/// Create an event listener.
-///
-/// `event` is the type of event to listen for, e.g. `"click"`. The `callback`
-/// is the function that will be invoked when the event occurs.
-///
-/// # Example
-///
-/// ```no_run
-/// use dioxus::{builder::*, bumpalo::Bump};
-///
-/// let b = Bump::new();
-///
-/// let listener = on(&b, "click", |root, vdom, event| {
-///     // do something when a click happens...
-/// });
-/// ```
-pub fn on<'a, 'b>(
-    // pub fn on<'a, 'b, F: 'static>(
-    bump: &'a Bump,
-    event: &'static str,
-    callback: impl Fn(VirtualEvent) + 'a,
-) -> Listener<'a> {
-    Listener {
-        event,
-        callback: bump.alloc(callback),
-    }
-}
+// /// Create an event listener.
+// ///
+// /// `event` is the type of event to listen for, e.g. `"click"`. The `callback`
+// /// is the function that will be invoked when the event occurs.
+// ///
+// /// # Example
+// ///
+// /// ```no_run
+// /// use dioxus::{builder::*, bumpalo::Bump};
+// ///
+// /// let b = Bump::new();
+// ///
+// /// let listener = on(&b, "click", |root, vdom, event| {
+// ///     // do something when a click happens...
+// /// });
+// /// ```
+// pub fn on<'a, 'b>(
+//     // pub fn on<'a, 'b, F: 'static>(
+//     bump: &'a Bump,
+//     event: &'static str,
+//     callback: impl Fn(VirtualEvent) + 'a,
+// ) -> Listener<'a> {
+//     Listener {
+//         event,
+//         callback: bump.alloc(callback),
+//     }
+// }
 
 pub fn virtual_child<'a, T>(_bump: &'a Bump, _props: T, _f: crate::innerlude::FC<T>) -> VNode<'a> {
     todo!()

+ 6 - 3
packages/core/src/nodes.rs

@@ -97,6 +97,8 @@ mod velement {
 
     // use crate::{events::VirtualEvent, innerlude::CbIdx};
 
+    use crate::{events::VirtualEvent, innerlude::ScopeIdx};
+
     use super::*;
     use std::fmt::Debug;
 
@@ -182,7 +184,8 @@ mod velement {
 
     pub struct ListenerHandle {
         pub event: &'static str,
-        pub idx: CbIdx,
+        pub scope: ScopeIdx,
+        pub id: usize,
     }
 
     /// An event listener.
@@ -190,8 +193,8 @@ mod velement {
         /// The type of event to listen for.
         pub(crate) event: &'static str,
 
-        // ref to the real listener
-        // pub(crate) id: u32,
+        pub scope: ScopeIdx,
+        pub id: usize,
 
         // pub(crate) _i: &'bump str,
         // #[serde(skip_serializing, skip_deserializing, default="")]

+ 34 - 51
packages/core/src/patch.rs

@@ -58,7 +58,15 @@ pub enum Edit<'d> {
     PopPushReverseChild { n: u32 },
     RemoveChild { n: u32 },
     SetClass { class_name: &'d str },
-    PushKnown { node: ScopeIdx },
+
+    // push a known node on to the stack
+    TraverseToKnown { node: ScopeIdx },
+
+    // Add the current top of the stack to the known nodes
+    MakeKnown { node: ScopeIdx },
+
+    // Remove the current top of the stack from the known nodes
+    RemoveKnown,
 }
 
 pub type EditList<'src> = Vec<Edit<'src>>;
@@ -67,7 +75,6 @@ pub struct EditMachine<'src> {
     pub traversal: Traversal,
     next_temporary: u32,
     forcing_new_listeners: bool,
-
     pub emitter: EditList<'src>,
 }
 
@@ -80,8 +87,12 @@ impl<'b> EditMachine<'b> {
             emitter: EditList::default(),
         }
     }
+}
 
-    /// Traversal methods.
+// ===================================
+//  Traversal Methods
+// ===================================
+impl<'b> EditMachine<'b> {
     pub fn go_down(&mut self) {
         self.traversal.down();
     }
@@ -158,6 +169,9 @@ impl<'b> EditMachine<'b> {
     }
 }
 
+// ===================================
+//  Stack methods
+// ===================================
 impl<'a> EditMachine<'a> {
     pub fn next_temporary(&self) -> u32 {
         self.next_temporary
@@ -205,11 +219,6 @@ impl<'a> EditMachine<'a> {
         self.emitter.push(Edit::InsertBefore {})
     }
 
-    pub fn ensure_string(&mut self, _string: &str) -> StringKey {
-        todo!()
-        // self.strings.ensure_string(string, &self.emitter)
-    }
-
     pub fn set_text(&mut self, text: &'a str) {
         debug_assert!(self.traversal_is_committed());
         // debug!("emit: set_text({:?})", text);
@@ -307,42 +316,26 @@ impl<'a> EditMachine<'a> {
         self.forcing_new_listeners = previous;
     }
 
-    pub fn new_event_listener(&mut self, event: &'a str, idx: CbIdx) {
+    pub fn new_event_listener(&mut self, event: &'a str, scope: ScopeIdx, id: usize) {
         debug_assert!(self.traversal_is_committed());
         self.emitter.push(Edit::NewEventListener {
             event_type: event,
-            s: idx,
+            s: scope,
         });
-        // todo!("Event listener not wired up yet");
         // log::debug!("emit: new_event_listener({:?})", listener);
-        // let (a, b) = listener.get_callback_parts();
-        // debug_assert!(a != 0);
-        // // let event_id = self.ensure_string(listener.event);
-        // self.emitter.new_event_listener(listener.event.into(), a, b);
     }
 
-    pub fn update_event_listener(&mut self, event: &'a str, idx: CbIdx) {
+    pub fn update_event_listener(&mut self, event: &'a str, scope: ScopeIdx, id: usize) {
         debug_assert!(self.traversal_is_committed());
         if self.forcing_new_listeners {
-            self.new_event_listener(event, idx);
+            self.new_event_listener(event, scope, id);
             return;
         }
 
         self.emitter.push(Edit::NewEventListener {
             event_type: event,
-            s: idx,
+            s: scope,
         });
-
-        // log::debug!("emit: update_event_listener({:?})", listener);
-        // // todo!("Event listener not wired up yet");
-        // let (a, b) = listener.get_callback_parts();
-        // debug_assert!(a != 0);
-        // self.emitter.push(Edit::UpdateEventListener {
-        //     event_type: listener.event.into(),
-        //     a,
-        //     b,
-        // });
-        // self.emitter.update_event_listener(event_id.into(), a, b);
     }
 
     pub fn remove_event_listener(&mut self, event: &'a str) {
@@ -350,16 +343,8 @@ impl<'a> EditMachine<'a> {
         self.emitter
             .push(Edit::RemoveEventListener { event_type: event });
         // debug!("emit: remove_event_listener({:?})", event);
-        // let _event_id = self.ensure_string(event);
-        // todo!("Event listener not wired up yet");
-        // self.emitter.remove_event_listener(event_id.into());
     }
 
-    // #[inline]
-    // pub fn has_template(&mut self, id: CacheId) -> bool {
-    //     self.templates.contains(&id)
-    // }
-
     // pub fn save_template(&mut self, id: CacheId) {
     //     debug_assert!(self.traversal_is_committed());
     //     debug_assert!(!self.has_template(id));
@@ -516,10 +501,8 @@ impl Traversal {
     /// Commit this traversals moves and return the optimized path from the last
     /// commit.
     #[inline]
-    pub fn commit(&mut self) -> Moves {
-        Moves {
-            inner: self.uncommitted.drain(..),
-        }
+    pub fn commit(&mut self) -> std::vec::Drain<'_, MoveTo> {
+        self.uncommitted.drain(..)
     }
 
     #[inline]
@@ -528,18 +511,18 @@ impl Traversal {
     }
 }
 
-pub struct Moves<'a> {
-    inner: std::vec::Drain<'a, MoveTo>,
-}
+// pub struct Moves<'a> {
+//     inner: std::vec::Drain<'a, MoveTo>,
+// }
 
-impl Iterator for Moves<'_> {
-    type Item = MoveTo;
+// impl Iterator for Moves<'_> {
+//     type Item = MoveTo;
 
-    #[inline]
-    fn next(&mut self) -> Option<MoveTo> {
-        self.inner.next()
-    }
-}
+//     #[inline]
+//     fn next(&mut self) -> Option<MoveTo> {
+//         self.inner.next()
+//     }
+// }
 
 #[cfg(test)]
 mod tests {

+ 52 - 30
packages/core/src/scope.rs

@@ -45,13 +45,21 @@ pub struct Scope {
     // lying, cheating reference >:(
     pub props: Box<dyn std::any::Any>,
 
+    // our own index
+    pub myidx: ScopeIdx,
+
     // pub props_type: TypeId,
     pub caller: *const (),
 }
 
 impl Scope {
     // create a new scope from a function
-    pub fn new<'a, P1, P2: 'static>(f: FC<P1>, props: P1, parent: Option<ScopeIdx>) -> Self {
+    pub fn new<'a, P1, P2: 'static>(
+        f: FC<P1>,
+        props: P1,
+        myidx: ScopeIdx,
+        parent: Option<ScopeIdx>,
+    ) -> Self {
         let hook_arena = typed_arena::Arena::new();
         let hooks = RefCell::new(Vec::new());
 
@@ -79,6 +87,7 @@ impl Scope {
         let props = unsafe { std::mem::transmute::<_, Box<P2>>(props) };
 
         Self {
+            myidx,
             hook_arena,
             hooks,
             caller,
@@ -109,6 +118,7 @@ impl Scope {
             idx: 0.into(),
             _p: PhantomData {},
             final_nodes: node_slot.clone(),
+            scope: self.myidx,
         };
 
         unsafe {
@@ -276,25 +286,34 @@ mod tests {
 
     #[test]
     fn check_listeners() -> Result<()> {
-        let mut scope = Scope::new::<(), ()>(ListenerTest, (), None);
-        scope.run::<()>();
+        todo!()
+        // let mut scope = Scope::new::<(), ()>(ListenerTest, (), None);
+        // scope.run::<()>();
 
-        let nodes = scope.new_frame();
-        dbg!(nodes);
+        // let nodes = scope.new_frame();
+        // dbg!(nodes);
 
-        Ok(())
+        // Ok(())
     }
 
     #[test]
     fn test_scope() {
         let example: FC<()> = |ctx, props| {
             use crate::builder::*;
-            ctx.render(|ctx| div(ctx.bump()).child(text("a")).finish())
+            ctx.render(|ctx| {
+                builder::ElementBuilder::new(ctx, "div")
+                    .child(text("a"))
+                    .finish()
+            })
         };
 
         let props = ();
         let parent = None;
-        let scope = Scope::new::<(), ()>(example, props, parent);
+        let mut nodes = generational_arena::Arena::new();
+        nodes.insert_with(|f| {
+            let scope = Scope::new::<(), ()>(example, props, f, parent);
+            //
+        });
     }
 
     #[derive(Debug)]
@@ -320,39 +339,42 @@ mod tests {
         let childprops: ExampleProps<'a> = ExampleProps { name: content };
         // let childprops: ExampleProps<'a> = ExampleProps { name: content };
         ctx.render(move |ctx| {
-            let b = ctx.bump();
-            div(b)
-                .child(text(props.name))
-                // .child(text(props.name))
-                .child(virtual_child::<ExampleProps>(b, childprops, child_example))
-                // .child(virtual_child::<ExampleProps<'a>>(b, childprops, CHILD))
-                // as for<'scope> fn(Context<'_>, &'scope ExampleProps<'scope>) -> DomTree
-                // |ctx, pops| todo!(),
-                // .child(virtual_child::<'a>(
-                //     b,
-                //     child_example,
-                //     ExampleProps { name: text },
-                // ))
-                .finish()
+            todo!()
+            // let b = ctx.bump();
+            // div(b)
+            //     .child(text(props.name))
+            //     // .child(text(props.name))
+            //     .child(virtual_child::<ExampleProps>(b, childprops, child_example))
+            //     // .child(virtual_child::<ExampleProps<'a>>(b, childprops, CHILD))
+            //     // as for<'scope> fn(Context<'_>, &'scope ExampleProps<'scope>) -> DomTree
+            //     // |ctx, pops| todo!(),
+            //     // .child(virtual_child::<'a>(
+            //     //     b,
+            //     //     child_example,
+            //     //     ExampleProps { name: text },
+            //     // ))
+            //     .finish()
         })
     }
 
     fn child_example<'b>(ctx: Context<'b>, props: &'b ExampleProps) -> DomTree {
         ctx.render(move |ctx| {
-            div(ctx.bump())
-                .child(text(props.name))
-                //
-                .finish()
+            todo!()
+            // div(ctx.bump())
+            //     .child(text(props.name))
+            //     //
+            //     .finish()
         })
     }
 
     static CHILD: FC<ExampleProps> = |ctx, props: &'_ ExampleProps| {
         // todo!()
         ctx.render(move |ctx| {
-            div(ctx.bump())
-                .child(text(props.name))
-                //
-                .finish()
+            todo!()
+            // div(ctx.bump())
+            //     .child(text(props.name))
+            //     //
+            //     .finish()
         })
     };
     #[test]

+ 8 - 6
packages/core/src/virtual_dom.rs

@@ -56,7 +56,8 @@ impl VirtualDom {
         // Create a reference to the component in the arena
         // Note: we are essentially running the "Mount" lifecycle event manually while the vdom doesnt yet exist
         // This puts the dom in a usable state on creation, rather than being potentially invalid
-        let base_scope = components.insert(Scope::new::<_, P>(root, root_props, None));
+        let base_scope =
+            components.insert_with(|id| Scope::new::<_, P>(root, root_props, id, None));
 
         // evaluate the component, pushing any updates its generates into the lifecycle queue
         // todo!
@@ -277,11 +278,12 @@ mod tests {
     #[test]
     fn start_dom() {
         let mut dom = VirtualDom::new(|ctx, props| {
-            ctx.render(|ctx| {
-                use crate::builder::*;
-                let bump = ctx.bump();
-                div(bump).child(text("hello,    world")).finish()
-            })
+            todo!()
+            // ctx.render(|ctx| {
+            //     use crate::builder::*;
+            //     let bump = ctx.bump();
+            //     div(bump).child(text("hello,    world")).finish()
+            // })
         });
         let edits = dom.rebuild().unwrap();
         println!("{:#?}", edits);

+ 20 - 0
packages/web/examples/query.rs

@@ -0,0 +1,20 @@
+// use dioxus_core::prelude::*;
+// use dioxus_web::WebsysRenderer;
+
+// fn main() {
+//     wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example));
+// }
+
+// fn Example(ctx: Context, props: ()) -> DomTree {
+//     let user_data = use_sql_query(&ctx, USER_DATA_QUERY);
+
+//     ctx.render(rsx! {
+//         h1 { "Hello, {username}"}
+//         button {
+//             "Delete user"
+//             onclick: move |_| user_data.delete()
+//         }
+//     })
+// }
+
+fn main() {}

+ 19 - 0
packages/web/src/old/virtual_node_test_utils.rs

@@ -139,3 +139,22 @@ mod tests {
         assert_eq!(hello_nodes.len(), 1);
     }
 }
+
+use dioxus_core::prelude::*;
+use dioxus_web::WebsysRenderer;
+
+fn main() {
+    wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example));
+}
+
+fn Component(ctx: Context, props: ()) -> DomTree {
+    let user_data = use_sql_query(&ctx, USER_DATA_QUERY);
+
+    ctx.render(rsx! {
+        h1 { "Hello, {username}"}
+        button {
+            "Delete user"
+            onclick: move |_| user_data.delete()
+        }
+    })
+}