Feat: listeners now have scope information

This commit is contained in:
Jonathan Kelley committed 2021-03-03 11:13:46 -05:00
1 parent cb74d70f83
commit fcd68e61d2
17 files changed
+897 -906

No files matched your search

+1 -1
View File
@@ -149,7 +149,7 @@ impl ToTokens for ToToksCtx<&Element> {
// let ctx = self.ctx; // let ctx = self.ctx;
let name = &self.inner.name; let name = &self.inner.name;
tokens.append_all(quote! { tokens.append_all(quote! {
dioxus::builder::#name(bump) dioxus::builder::ElementBuilder::new(ctx, "#name")
}); });
for attr in self.inner.attrs.iter() { for attr in self.inner.attrs.iter() {
self.recurse(attr).to_tokens(tokens); self.recurse(attr).to_tokens(tokens);
+1 -1
View File
@@ -146,7 +146,7 @@ impl ToTokens for ToToksCtx<&Element> {
// // let ctx = self.ctx; // // let ctx = self.ctx;
let name = &self.inner.name; let name = &self.inner.name;
tokens.append_all(quote! { tokens.append_all(quote! {
dioxus::builder::#name(bump) dioxus::builder::ElementBuilder::new(ctx, "#name")
}); });
for attr in self.inner.attrs.iter() { for attr in self.inner.attrs.iter() {
self.recurse(attr).to_tokens(tokens); self.recurse(attr).to_tokens(tokens);
+75 -75
View File
@@ -1,93 +1,93 @@
//! An alternative function syntax // //! An alternative function syntax
//! // //!
use bumpalo::Bump; // use bumpalo::Bump;
use dioxus_core::prelude::VNode; // use dioxus_core::prelude::VNode;
fn main() {} fn main() {}
struct Context2<'a, P> { // struct Context2<'a, P> {
_props: &'a P, // _p: PhantomData<&'a ()>, // _props: &'a P, // _p: PhantomData<&'a ()>,
rops: &'a P, // _p: PhantomData<&'a ()>, // rops: &'a P, // _p: PhantomData<&'a ()>,
} // }
impl<'a, P> Context2<'a, P> { // impl<'a, P> Context2<'a, P> {
fn render(self, _f: impl FnOnce(&'a Bump) -> VNode<'a>) -> DTree { // fn render(self, _f: impl FnOnce(&'a Bump) -> VNode<'a>) -> DTree {
DTree {} // DTree {}
} // }
fn props(&self) -> &'a P { // fn props(&self) -> &'a P {
todo!() // todo!()
} // }
pub fn use_hook<'scope, InternalHookState: 'static, Output: 'a>( // pub fn use_hook<'scope, InternalHookState: 'static, Output: 'a>(
&'scope self, // &'scope self,
_initializer: impl FnOnce() -> InternalHookState, // _initializer: impl FnOnce() -> InternalHookState,
_runner: impl FnOnce(&'a mut InternalHookState) -> Output, // _runner: impl FnOnce(&'a mut InternalHookState) -> Output,
_cleanup: impl FnOnce(InternalHookState), // _cleanup: impl FnOnce(InternalHookState),
) -> Output { // ) -> Output {
todo!() // todo!()
} // }
} // }
trait Properties {} // trait Properties {}
struct DTree; // struct DTree;
// type FC2<'a, T: 'a> = fn(Context2<T>) -> 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> { // fn virtual_child<'a, T: 'a>(_bump: &'a Bump, _props: T, _f: FC2<T>) -> VNode<'a> {
todo!() // todo!()
} // }
struct Props { // struct Props {
c: String, // c: String,
} // }
fn Example(ctx: Context2<Props>) -> DTree { // fn Example(ctx: Context2<Props>) -> DTree {
let val = use_state(&ctx, || String::from("asd")); // let val = use_state(&ctx, || String::from("asd"));
let props = ctx.props(); // let props = ctx.props();
ctx.render(move |b| { // ctx.render(move |b| {
dioxus_core::nodebuilder::div(b) // dioxus_core::nodebuilder::div(b)
.child(dioxus_core::nodebuilder::text(props.c.as_str())) // .child(dioxus_core::nodebuilder::text(props.c.as_str()))
.child(virtual_child(b, Props2 { a: val }, AltChild)) // .child(virtual_child(b, Props2 { a: val }, AltChild))
.finish() // .finish()
}) // })
} // }
// #[fc] // // #[fc]
fn Example2(ctx: Context2<()>, name: &str, _blah: &str) -> DTree { // fn Example2(ctx: Context2<()>, name: &str, _blah: &str) -> DTree {
let val = use_state(&ctx, || String::from("asd")); // let val = use_state(&ctx, || String::from("asd"));
ctx.render(move |b| { // ctx.render(move |ctx| {
dioxus_core::nodebuilder::div(b) // dioxus_core::builder::ElementBuilder::new(b, "div")
.child(dioxus_core::nodebuilder::text(name)) // .child(dioxus_core::nodebuilder::text(name))
.child(virtual_child(b, Props2 { a: val }, AltChild)) // .child(virtual_child(b, Props2 { a: val }, AltChild))
.finish() // .finish()
}) // })
} // }
type FC2<'a, T> = fn(Context2<T>) -> DTree; // 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) // // still works if you don't take any references in your props (ie, something copy or cloneable)
static CHILD: FC2<Props2> = |_ctx: Context2<Props2>| { // static CHILD: FC2<Props2> = |_ctx: Context2<Props2>| {
// // //
todo!() // todo!()
}; // };
struct Props2<'a> { // struct Props2<'a> {
a: &'a String, // a: &'a String,
} // }
impl Properties for Props2<'_> {} // impl Properties for Props2<'_> {}
fn AltChild(ctx: Context2<Props2>) -> DTree { // fn AltChild(ctx: Context2<Props2>) -> DTree {
ctx.render(|_b| { // ctx.render(|_b| {
// // //
todo!() // todo!()
}) // })
} // }
fn use_state<'a, 'c, P, T: 'static, F: FnOnce() -> T>( // fn use_state<'a, 'c, P, T: 'static, F: FnOnce() -> T>(
_ctx: &'_ Context2<'a, P>, // _ctx: &'_ Context2<'a, P>,
_initial_state_fn: F, // _initial_state_fn: F,
) -> &'a T { // ) -> &'a T {
todo!() // todo!()
} // }
+2 -2
View File
@@ -22,12 +22,12 @@ fn app(ctx: Context, props: &Props) -> DomTree {
let (f, setter) = use_state(&ctx, || 0); let (f, setter) = use_state(&ctx, || 0);
ctx.render(move |b| { ctx.render(move |b| {
let mut root = builder::div(b); let mut root = builder::ElementBuilder::new(b, "div");
for child in &props.items { for child in &props.items {
// notice that the child directly borrows from our vec // notice that the child directly borrows from our vec
// this makes lists very fast (simply views reusing lifetimes) // this makes lists very fast (simply views reusing lifetimes)
root = root.child(builder::virtual_child( root = root.child(builder::virtual_child(
b, b.bump,
ChildProps { ChildProps {
item: child, item: child,
item_handler: setter, item_handler: setter,
+1 -2
View File
@@ -1,4 +1,3 @@
use builder::button;
use dioxus_core::prelude::*; use dioxus_core::prelude::*;
fn main() {} fn main() {}
@@ -15,7 +14,7 @@ static Example: FC<Props> = |ctx, props| {
let value = ctx.use_context(|c: &SomeContext| c.items.last().unwrap()); let value = ctx.use_context(|c: &SomeContext| c.items.last().unwrap());
ctx.render(move |bump| { ctx.render(move |bump| {
button(bump) builder::ElementBuilder::new(bump, "button")
.on("click", move |_| { .on("click", move |_| {
println!("Value is {}", props.name); println!("Value is {}", props.name);
println!("Value is {}", value.as_str()); println!("Value is {}", value.as_str());
+1 -1
View File
@@ -13,7 +13,7 @@ static Header: FC<()> = |ctx, props| {
let handler1 = move || println!("Value is {}", inner.current()); let handler1 = move || println!("Value is {}", inner.current());
ctx.render(|bump| { ctx.render(|bump| {
builder::div(bump) builder::ElementBuilder::new(bump, "div")
.child(VNode::Component(VComponent::new( .child(VNode::Component(VComponent::new(
Bottom, Bottom,
// //
+589
View File
@@ -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
View File
@@ -48,6 +48,7 @@ mod tests {
ctx.render(html! { ctx.render(html! {
<div> <div>
</div> </div>
}) })
}; };
+16 -6
View File
@@ -31,6 +31,8 @@ use std::{
pub struct Context<'src> { pub struct Context<'src> {
pub idx: AtomicUsize, pub idx: AtomicUsize,
pub scope: ScopeIdx,
// Borrowed from scope // Borrowed from scope
pub(crate) arena: &'src typed_arena::Arena<Hook>, pub(crate) arena: &'src typed_arena::Arena<Hook>,
pub(crate) hooks: &'src RefCell<Vec<*mut Hook>>, pub(crate) hooks: &'src RefCell<Vec<*mut Hook>>,
@@ -76,12 +78,17 @@ impl<'a> Context<'a> {
/// ctx.render(lazy_tree) /// ctx.render(lazy_tree)
/// } /// }
///``` ///```
pub fn render(self, lazy_nodes: impl FnOnce(NodeCtx<'a>) -> VNode<'a> + 'a) -> DomTree { pub fn render(self, lazy_nodes: impl FnOnce(&'a NodeCtx<'a>) -> VNode<'a> + 'a) -> DomTree {
let ctx = NodeCtx { bump: self.bump }; let ctx = NodeCtx {
let safe_nodes = lazy_nodes(ctx); 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) }; // let unsafe_nodes = unsafe { std::mem::transmute::<VNode<'a>, VNode<'static>>(safe_nodes) };
self.final_nodes.deref().borrow_mut().replace(unsafe_nodes); // self.final_nodes.deref().borrow_mut().replace(unsafe_nodes);
DomTree {} DomTree {}
} }
@@ -100,8 +107,11 @@ impl<'a> Context<'a> {
// NodeCtx is used to build VNodes in the component's memory space. // 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 // This struct adds metadata to the final DomTree about listeners, attributes, and children
#[derive(Debug, Clone)]
pub struct NodeCtx<'a> { pub struct NodeCtx<'a> {
bump: &'a Bump, pub bump: &'a Bump,
pub idx: RefCell<usize>,
pub scope: ScopeIdx,
} }
impl NodeCtx<'_> { impl NodeCtx<'_> {
+20 -97
View File
@@ -78,12 +78,6 @@ impl<'a> DiffMachine<'a> {
new: &VNode<'a>, new: &VNode<'a>,
// scope: Option<generational_arena::Index>, // 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. 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. 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(_)) => { (VNode::Text(_), VNode::Element(_)) => {
// TODO: Hook up the events properly // TODO: Hook up the events properly
// todo!("Hook up events registry"); // todo!("Hook up events registry");
@@ -109,112 +102,37 @@ impl<'a> DiffMachine<'a> {
self.change_list.replace_with(); self.change_list.replace_with();
} }
// Definitely different, need to commit update
(VNode::Element(_), VNode::Text(_)) => { (VNode::Element(_), VNode::Text(_)) => {
self.change_list.commit_traversal(); self.change_list.commit_traversal();
self.create(new); 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(); self.change_list.replace_with();
} }
// compare elements
// if different, schedule different types of update
(VNode::Element(eold), VNode::Element(enew)) => { (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 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 { if enew.tag_name != eold.tag_name || enew.namespace != eold.namespace {
self.change_list.commit_traversal(); self.change_list.commit_traversal();
// create(cached_set, self.change_list, registry, new, cached_roots);
// registry.remove_subtree(&old);
self.change_list.replace_with(); self.change_list.replace_with();
return; return;
} }
self.diff_listeners(eold.listeners, enew.listeners); self.diff_listeners(eold.listeners, enew.listeners);
self.diff_attr(eold.attributes, enew.attributes, enew.namespace.is_some()); self.diff_attr(eold.attributes, enew.attributes, enew.namespace.is_some());
self.diff_children(eold.children, enew.children); 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(_)) => { (VNode::Component(_), VNode::Component(_)) => {
todo!("Usage of component VNode not currently supported"); 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(_)) => { (_, VNode::Component(_)) => {
todo!("Usage of component VNode not currently supported"); 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(_), _) => { (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"); todo!("Usage of component VNode not currently supported");
} }
// A suspended component appeared!
// Don't do much, just wait
(VNode::Suspended, _) | (_, VNode::Suspended) => { (VNode::Suspended, _) | (_, VNode::Suspended) => {
// (VNode::Element(_), VNode::Suspended) => {} // (VNode::Element(_), VNode::Suspended) => {}
// (VNode::Text(_), VNode::Suspended) => {} // (VNode::Text(_), VNode::Suspended) => {}
@@ -254,17 +172,19 @@ impl<'a> DiffMachine<'a> {
if new_l.event == old_l.event { if new_l.event == old_l.event {
// if let Some(scope) = self.current_idx { // if let Some(scope) = self.current_idx {
// let cb = CbIdx::from_gi_index(scope, l_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; continue 'outer1;
} }
} }
if let Some(scope) = self.current_idx { // if let Some(scope) = self.current_idx {
let cb = CbIdx::from_gi_index(scope, l_idx); // let cb = CbIdx::from_gi_index(scope, l_idx);
self.change_list.new_event_listener(event_type, cb); self.change_list
} .new_event_listener(event_type, new_l.scope, new_l.id);
// }
} }
'outer2: for old_l in old { 'outer2: for old_l in old {
@@ -893,14 +813,17 @@ impl<'a> DiffMachine<'a> {
} }
listeners.iter().enumerate().for_each(|(id, listener)| { listeners.iter().enumerate().for_each(|(id, listener)| {
if let Some(index) = self.current_idx { // if let Some(index) = self.current_idx {
self.change_list self.change_list.new_event_listener(
.new_event_listener(listener.event, CbIdx::from_gi_index(index, id)); listener.event,
} else { listener.scope,
// Don't panic listener.id,
// Used for testing );
log::trace!("Failed to set listener, create was not called in the context of the virtual dom"); // } 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 { // for l in listeners {
// unsafe { // unsafe {
+51 -631
View File
@@ -3,6 +3,7 @@
use std::ops::Deref; use std::ops::Deref;
use crate::{ use crate::{
context::NodeCtx,
events::VirtualEvent, events::VirtualEvent,
innerlude::VComponent, innerlude::VComponent,
nodes::{Attribute, Listener, NodeKey, VNode}, nodes::{Attribute, Listener, NodeKey, VNode},
@@ -17,14 +18,14 @@ use bumpalo::Bump;
/// Typically constructed with element-specific constructors, eg the `div` /// Typically constructed with element-specific constructors, eg the `div`
/// function for building `<div>` elements or the `button` function for building /// function for building `<div>` elements or the `button` function for building
/// `<button>` elements. /// `<button>` elements.
#[derive(Clone, Debug)] #[derive(Debug)]
pub struct ElementBuilder<'a, Listeners, Attributes, Children> pub struct ElementBuilder<'a, Listeners, Attributes, Children>
where where
Listeners: 'a + AsRef<[Listener<'a>]>, Listeners: 'a + AsRef<[Listener<'a>]>,
Attributes: 'a + AsRef<[Attribute<'a>]>, Attributes: 'a + AsRef<[Attribute<'a>]>,
Children: 'a + AsRef<[VNode<'a>]>, Children: 'a + AsRef<[VNode<'a>]>,
{ {
bump: &'a Bump, ctx: &'a NodeCtx<'a>,
key: NodeKey, key: NodeKey,
tag_name: &'a str, tag_name: &'a str,
listeners: Listeners, listeners: Listeners,
@@ -64,13 +65,11 @@ impl<'a>
/// let my_element_builder = ElementBuilder::new(&b, tag_name); /// let my_element_builder = ElementBuilder::new(&b, tag_name);
/// # fn flip_coin() -> bool { true } /// # fn flip_coin() -> bool { true }
/// ``` /// ```
pub fn new<B>(bump: B, tag_name: &'a str) -> Self pub fn new(ctx: &'a NodeCtx<'a>, tag_name: &'static str) -> Self {
where // pub fn new<B>(ctx: &'a mut NodeCtx<'a>, tag_name: &'a str) -> Self {
B: Into<&'a Bump>, let bump = ctx.bump();
{
let bump = bump.into();
ElementBuilder { ElementBuilder {
bump, ctx,
key: NodeKey::NONE, key: NodeKey::NONE,
tag_name, tag_name,
listeners: bumpalo::collections::Vec::new_in(bump), listeners: bumpalo::collections::Vec::new_in(bump),
@@ -120,7 +119,7 @@ where
L: 'a + AsRef<[Listener<'a>]>, L: 'a + AsRef<[Listener<'a>]>,
{ {
ElementBuilder { ElementBuilder {
bump: self.bump, ctx: self.ctx,
key: self.key, key: self.key,
tag_name: self.tag_name, tag_name: self.tag_name,
listeners, listeners,
@@ -159,7 +158,7 @@ where
A: 'a + AsRef<[Attribute<'a>]>, A: 'a + AsRef<[Attribute<'a>]>,
{ {
ElementBuilder { ElementBuilder {
bump: self.bump, ctx: self.ctx,
key: self.key, key: self.key,
tag_name: self.tag_name, tag_name: self.tag_name,
listeners: self.listeners, listeners: self.listeners,
@@ -198,7 +197,7 @@ where
C: 'a + AsRef<[VNode<'a>]>, C: 'a + AsRef<[VNode<'a>]>,
{ {
ElementBuilder { ElementBuilder {
bump: self.bump, ctx: self.ctx,
key: self.key, key: self.key,
tag_name: self.tag_name, tag_name: self.tag_name,
listeners: self.listeners, listeners: self.listeners,
@@ -225,7 +224,7 @@ where
#[inline] #[inline]
pub fn namespace(self, namespace: Option<&'a str>) -> Self { pub fn namespace(self, namespace: Option<&'a str>) -> Self {
ElementBuilder { ElementBuilder {
bump: self.bump, ctx: self.ctx,
key: self.key, key: self.key,
tag_name: self.tag_name, tag_name: self.tag_name,
listeners: self.listeners, listeners: self.listeners,
@@ -291,17 +290,17 @@ where
/// ``` /// ```
#[inline] #[inline]
pub fn finish(self) -> VNode<'a> { 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 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 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(); let attributes: &'a [Attribute<'a>] = attributes.as_ref();
VNode::element( VNode::element(
self.bump, self.ctx.bump(),
self.key, self.key,
self.tag_name, self.tag_name,
listeners, listeners,
@@ -340,10 +339,18 @@ where
/// ``` /// ```
#[inline] #[inline]
pub fn on(mut self, event: &'static str, callback: impl Fn(VirtualEvent) + 'a) -> Self { 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 { self.listeners.push(Listener {
event, 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 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. /// Construct a text VNode.
/// ///
/// This is `dioxus`'s virtual DOM equivalent of `document.createTextVNode`. /// 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 } Attribute { name, value }
} }
/// Create an event listener. // /// Create an event listener.
/// // ///
/// `event` is the type of event to listen for, e.g. `"click"`. The `callback` // /// `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. // /// is the function that will be invoked when the event occurs.
/// // ///
/// # Example // /// # Example
/// // ///
/// ```no_run // /// ```no_run
/// use dioxus::{builder::*, bumpalo::Bump}; // /// use dioxus::{builder::*, bumpalo::Bump};
/// // ///
/// let b = Bump::new(); // /// let b = Bump::new();
/// // ///
/// let listener = on(&b, "click", |root, vdom, event| { // /// let listener = on(&b, "click", |root, vdom, event| {
/// // do something when a click happens... // /// // do something when a click happens...
/// }); // /// });
/// ``` // /// ```
pub fn on<'a, 'b>( // pub fn on<'a, 'b>(
// pub fn on<'a, 'b, F: 'static>( // // pub fn on<'a, 'b, F: 'static>(
bump: &'a Bump, // bump: &'a Bump,
event: &'static str, // event: &'static str,
callback: impl Fn(VirtualEvent) + 'a, // callback: impl Fn(VirtualEvent) + 'a,
) -> Listener<'a> { // ) -> Listener<'a> {
Listener { // Listener {
event, // event,
callback: bump.alloc(callback), // callback: bump.alloc(callback),
} // }
} // }
pub fn virtual_child<'a, T>(_bump: &'a Bump, _props: T, _f: crate::innerlude::FC<T>) -> VNode<'a> { pub fn virtual_child<'a, T>(_bump: &'a Bump, _props: T, _f: crate::innerlude::FC<T>) -> VNode<'a> {
todo!() todo!()
+6 -3
View File
@@ -97,6 +97,8 @@ mod velement {
// use crate::{events::VirtualEvent, innerlude::CbIdx}; // use crate::{events::VirtualEvent, innerlude::CbIdx};
use crate::{events::VirtualEvent, innerlude::ScopeIdx};
use super::*; use super::*;
use std::fmt::Debug; use std::fmt::Debug;
@@ -182,7 +184,8 @@ mod velement {
pub struct ListenerHandle { pub struct ListenerHandle {
pub event: &'static str, pub event: &'static str,
pub idx: CbIdx, pub scope: ScopeIdx,
pub id: usize,
} }
/// An event listener. /// An event listener.
@@ -190,8 +193,8 @@ mod velement {
/// The type of event to listen for. /// The type of event to listen for.
pub(crate) event: &'static str, pub(crate) event: &'static str,
// ref to the real listener pub scope: ScopeIdx,
// pub(crate) id: u32, pub id: usize,
// pub(crate) _i: &'bump str, // pub(crate) _i: &'bump str,
// #[serde(skip_serializing, skip_deserializing, default="")] // #[serde(skip_serializing, skip_deserializing, default="")]
+34 -51
View File
@@ -58,7 +58,15 @@ pub enum Edit<'d> {
PopPushReverseChild { n: u32 }, PopPushReverseChild { n: u32 },
RemoveChild { n: u32 }, RemoveChild { n: u32 },
SetClass { class_name: &'d str }, 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>>; pub type EditList<'src> = Vec<Edit<'src>>;
@@ -67,7 +75,6 @@ pub struct EditMachine<'src> {
pub traversal: Traversal, pub traversal: Traversal,
next_temporary: u32, next_temporary: u32,
forcing_new_listeners: bool, forcing_new_listeners: bool,
pub emitter: EditList<'src>, pub emitter: EditList<'src>,
} }
@@ -80,8 +87,12 @@ impl<'b> EditMachine<'b> {
emitter: EditList::default(), emitter: EditList::default(),
} }
} }
}
/// Traversal methods. // ===================================
// Traversal Methods
// ===================================
impl<'b> EditMachine<'b> {
pub fn go_down(&mut self) { pub fn go_down(&mut self) {
self.traversal.down(); self.traversal.down();
} }
@@ -158,6 +169,9 @@ impl<'b> EditMachine<'b> {
} }
} }
// ===================================
// Stack methods
// ===================================
impl<'a> EditMachine<'a> { impl<'a> EditMachine<'a> {
pub fn next_temporary(&self) -> u32 { pub fn next_temporary(&self) -> u32 {
self.next_temporary self.next_temporary
@@ -205,11 +219,6 @@ impl<'a> EditMachine<'a> {
self.emitter.push(Edit::InsertBefore {}) 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) { pub fn set_text(&mut self, text: &'a str) {
debug_assert!(self.traversal_is_committed()); debug_assert!(self.traversal_is_committed());
// debug!("emit: set_text({:?})", text); // debug!("emit: set_text({:?})", text);
@@ -307,42 +316,26 @@ impl<'a> EditMachine<'a> {
self.forcing_new_listeners = previous; 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()); debug_assert!(self.traversal_is_committed());
self.emitter.push(Edit::NewEventListener { self.emitter.push(Edit::NewEventListener {
event_type: event, event_type: event,
s: idx, s: scope,
}); });
// todo!("Event listener not wired up yet");
// log::debug!("emit: new_event_listener({:?})", listener); // 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()); debug_assert!(self.traversal_is_committed());
if self.forcing_new_listeners { if self.forcing_new_listeners {
self.new_event_listener(event, idx); self.new_event_listener(event, scope, id);
return; return;
} }
self.emitter.push(Edit::NewEventListener { self.emitter.push(Edit::NewEventListener {
event_type: event, 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) { pub fn remove_event_listener(&mut self, event: &'a str) {
@@ -350,16 +343,8 @@ impl<'a> EditMachine<'a> {
self.emitter self.emitter
.push(Edit::RemoveEventListener { event_type: event }); .push(Edit::RemoveEventListener { event_type: event });
// debug!("emit: remove_event_listener({:?})", 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) { // pub fn save_template(&mut self, id: CacheId) {
// debug_assert!(self.traversal_is_committed()); // debug_assert!(self.traversal_is_committed());
// debug_assert!(!self.has_template(id)); // 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 this traversals moves and return the optimized path from the last
/// commit. /// commit.
#[inline] #[inline]
pub fn commit(&mut self) -> Moves { pub fn commit(&mut self) -> std::vec::Drain<'_, MoveTo> {
Moves { self.uncommitted.drain(..)
inner: self.uncommitted.drain(..),
}
} }
#[inline] #[inline]
@@ -528,18 +511,18 @@ impl Traversal {
} }
} }
pub struct Moves<'a> { // pub struct Moves<'a> {
inner: std::vec::Drain<'a, MoveTo>, // inner: std::vec::Drain<'a, MoveTo>,
} // }
impl Iterator for Moves<'_> { // impl Iterator for Moves<'_> {
type Item = MoveTo; // type Item = MoveTo;
#[inline] // #[inline]
fn next(&mut self) -> Option<MoveTo> { // fn next(&mut self) -> Option<MoveTo> {
self.inner.next() // self.inner.next()
} // }
} // }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
+52 -30
View File
@@ -45,13 +45,21 @@ pub struct Scope {
// lying, cheating reference >:( // lying, cheating reference >:(
pub props: Box<dyn std::any::Any>, pub props: Box<dyn std::any::Any>,
// our own index
pub myidx: ScopeIdx,
// pub props_type: TypeId, // pub props_type: TypeId,
pub caller: *const (), pub caller: *const (),
} }
impl Scope { impl Scope {
// create a new scope from a function // 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 hook_arena = typed_arena::Arena::new();
let hooks = RefCell::new(Vec::new()); let hooks = RefCell::new(Vec::new());
@@ -79,6 +87,7 @@ impl Scope {
let props = unsafe { std::mem::transmute::<_, Box<P2>>(props) }; let props = unsafe { std::mem::transmute::<_, Box<P2>>(props) };
Self { Self {
myidx,
hook_arena, hook_arena,
hooks, hooks,
caller, caller,
@@ -109,6 +118,7 @@ impl Scope {
idx: 0.into(), idx: 0.into(),
_p: PhantomData {}, _p: PhantomData {},
final_nodes: node_slot.clone(), final_nodes: node_slot.clone(),
scope: self.myidx,
}; };
unsafe { unsafe {
@@ -276,25 +286,34 @@ mod tests {
#[test] #[test]
fn check_listeners() -> Result<()> { fn check_listeners() -> Result<()> {
let mut scope = Scope::new::<(), ()>(ListenerTest, (), None); todo!()
scope.run::<()>(); // let mut scope = Scope::new::<(), ()>(ListenerTest, (), None);
// scope.run::<()>();
let nodes = scope.new_frame(); // let nodes = scope.new_frame();
dbg!(nodes); // dbg!(nodes);
Ok(()) // Ok(())
} }
#[test] #[test]
fn test_scope() { fn test_scope() {
let example: FC<()> = |ctx, props| { let example: FC<()> = |ctx, props| {
use crate::builder::*; 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 props = ();
let parent = None; 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)] #[derive(Debug)]
@@ -320,39 +339,42 @@ mod tests {
let childprops: ExampleProps<'a> = ExampleProps { name: content }; let childprops: ExampleProps<'a> = ExampleProps { name: content };
// let childprops: ExampleProps<'a> = ExampleProps { name: content }; // let childprops: ExampleProps<'a> = ExampleProps { name: content };
ctx.render(move |ctx| { ctx.render(move |ctx| {
let b = ctx.bump(); todo!()
div(b) // let b = ctx.bump();
.child(text(props.name)) // div(b)
// .child(text(props.name)) // .child(text(props.name))
.child(virtual_child::<ExampleProps>(b, childprops, child_example)) // // .child(text(props.name))
// .child(virtual_child::<ExampleProps<'a>>(b, childprops, CHILD)) // .child(virtual_child::<ExampleProps>(b, childprops, child_example))
// as for<'scope> fn(Context<'_>, &'scope ExampleProps<'scope>) -> DomTree // // .child(virtual_child::<ExampleProps<'a>>(b, childprops, CHILD))
// |ctx, pops| todo!(), // // as for<'scope> fn(Context<'_>, &'scope ExampleProps<'scope>) -> DomTree
// .child(virtual_child::<'a>( // // |ctx, pops| todo!(),
// b, // // .child(virtual_child::<'a>(
// child_example, // // b,
// ExampleProps { name: text }, // // child_example,
// )) // // ExampleProps { name: text },
.finish() // // ))
// .finish()
}) })
} }
fn child_example<'b>(ctx: Context<'b>, props: &'b ExampleProps) -> DomTree { fn child_example<'b>(ctx: Context<'b>, props: &'b ExampleProps) -> DomTree {
ctx.render(move |ctx| { ctx.render(move |ctx| {
div(ctx.bump()) todo!()
.child(text(props.name)) // div(ctx.bump())
// // .child(text(props.name))
.finish() // //
// .finish()
}) })
} }
static CHILD: FC<ExampleProps> = |ctx, props: &'_ ExampleProps| { static CHILD: FC<ExampleProps> = |ctx, props: &'_ ExampleProps| {
// todo!() // todo!()
ctx.render(move |ctx| { ctx.render(move |ctx| {
div(ctx.bump()) todo!()
.child(text(props.name)) // div(ctx.bump())
// // .child(text(props.name))
.finish() // //
// .finish()
}) })
}; };
#[test] #[test]
+8 -6
View File
@@ -56,7 +56,8 @@ impl VirtualDom {
// Create a reference to the component in the arena // 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 // 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 // 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 // evaluate the component, pushing any updates its generates into the lifecycle queue
// todo! // todo!
@@ -277,11 +278,12 @@ mod tests {
#[test] #[test]
fn start_dom() { fn start_dom() {
let mut dom = VirtualDom::new(|ctx, props| { let mut dom = VirtualDom::new(|ctx, props| {
ctx.render(|ctx| { todo!()
use crate::builder::*; // ctx.render(|ctx| {
let bump = ctx.bump(); // use crate::builder::*;
div(bump).child(text("hello, world")).finish() // let bump = ctx.bump();
}) // div(bump).child(text("hello, world")).finish()
// })
}); });
let edits = dom.rebuild().unwrap(); let edits = dom.rebuild().unwrap();
println!("{:#?}", edits); println!("{:#?}", edits);
+20
View File
@@ -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() {}
@@ -139,3 +139,22 @@ mod tests {
assert_eq!(hello_nodes.len(), 1); 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()
}
})
}