Feat: listeners now have scope information

This commit is contained in:
Jonathan Kelley 2021-03-03 11:13:46 -05:00
parent cb74d70f83
commit fcd68e61d2
17 changed files with 897 additions and 906 deletions

View file

@ -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);

View file

@ -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);

View file

@ -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 {}
}
// 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!()
}
// 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!()
}
}
// 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 {}
// 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 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,
}
// struct Props {
// c: String,
// }
fn Example(ctx: Context2<Props>) -> DTree {
let val = use_state(&ctx, || String::from("asd"));
let props = ctx.props();
// 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()
})
}
// 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"));
// // #[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()
})
}
// 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;
// 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!()
};
// // 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<'_> {}
// struct Props2<'a> {
// a: &'a String,
// }
// impl Properties for Props2<'_> {}
fn AltChild(ctx: Context2<Props2>) -> DTree {
ctx.render(|_b| {
//
todo!()
})
}
// 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!()
}
// fn use_state<'a, 'c, P, T: 'static, F: FnOnce() -> T>(
// _ctx: &'_ Context2<'a, P>,
// _initial_state_fn: F,
// ) -> &'a T {
// todo!()
// }

View file

@ -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,

View file

@ -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());

View file

@ -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,
//

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";
// }

View file

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

View file

@ -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);
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);
// 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<'_> {

View file

@ -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 {

View file

@ -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!()

View file

@ -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="")]

View file

@ -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 {

View file

@ -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]

View file

@ -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);

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() {}

View file

@ -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()
}
})
}