Feat: add context to builder
This commit is contained in:
1 parent
fcd68e61d2
commit
cf16090838
8 files changed
+144
-98
No files matched your search
@@ -78,17 +78,17 @@ impl<'a> Context<'a> {
|
||||
/// ctx.render(lazy_tree)
|
||||
/// }
|
||||
///```
|
||||
pub fn render(self, lazy_nodes: impl FnOnce(&'a NodeCtx<'a>) -> VNode<'a> + 'a) -> DomTree {
|
||||
pub fn render(self, lazy_nodes: impl FnOnce(&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);
|
||||
// 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 {}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,13 +19,13 @@ use bumpalo::Bump;
|
||||
/// function for building `<div>` elements or the `button` function for building
|
||||
/// `<button>` elements.
|
||||
#[derive(Debug)]
|
||||
pub struct ElementBuilder<'a, Listeners, Attributes, Children>
|
||||
pub struct ElementBuilder<'a, 'b, Listeners, Attributes, Children>
|
||||
where
|
||||
Listeners: 'a + AsRef<[Listener<'a>]>,
|
||||
Attributes: 'a + AsRef<[Attribute<'a>]>,
|
||||
Children: 'a + AsRef<[VNode<'a>]>,
|
||||
{
|
||||
ctx: &'a NodeCtx<'a>,
|
||||
ctx: &'b NodeCtx<'a>,
|
||||
key: NodeKey,
|
||||
tag_name: &'a str,
|
||||
listeners: Listeners,
|
||||
@@ -34,9 +34,10 @@ where
|
||||
namespace: Option<&'a str>,
|
||||
}
|
||||
|
||||
impl<'a>
|
||||
impl<'a, 'b>
|
||||
ElementBuilder<
|
||||
'a,
|
||||
'b,
|
||||
bumpalo::collections::Vec<'a, Listener<'a>>,
|
||||
bumpalo::collections::Vec<'a, Attribute<'a>>,
|
||||
bumpalo::collections::Vec<'a, VNode<'a>>,
|
||||
@@ -65,9 +66,9 @@ impl<'a>
|
||||
/// let my_element_builder = ElementBuilder::new(&b, tag_name);
|
||||
/// # fn flip_coin() -> bool { true }
|
||||
/// ```
|
||||
pub fn new(ctx: &'a NodeCtx<'a>, tag_name: &'static str) -> Self {
|
||||
pub fn new(ctx: &'b 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();
|
||||
let bump = ctx.bump;
|
||||
ElementBuilder {
|
||||
ctx,
|
||||
key: NodeKey::NONE,
|
||||
@@ -80,7 +81,8 @@ impl<'a>
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Listeners, Attributes, Children> ElementBuilder<'a, Listeners, Attributes, Children>
|
||||
impl<'a, 'b, Listeners, Attributes, Children>
|
||||
ElementBuilder<'a, 'b, Listeners, Attributes, Children>
|
||||
where
|
||||
Listeners: 'a + AsRef<[Listener<'a>]>,
|
||||
Attributes: 'a + AsRef<[Attribute<'a>]>,
|
||||
@@ -114,7 +116,7 @@ where
|
||||
/// .finish();
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn listeners<L>(self, listeners: L) -> ElementBuilder<'a, L, Attributes, Children>
|
||||
pub fn listeners<L>(self, listeners: L) -> ElementBuilder<'a, 'b, L, Attributes, Children>
|
||||
where
|
||||
L: 'a + AsRef<[Listener<'a>]>,
|
||||
{
|
||||
@@ -153,7 +155,7 @@ where
|
||||
/// .finish();
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn attributes<A>(self, attributes: A) -> ElementBuilder<'a, Listeners, A, Children>
|
||||
pub fn attributes<A>(self, attributes: A) -> ElementBuilder<'a, 'b, Listeners, A, Children>
|
||||
where
|
||||
A: 'a + AsRef<[Attribute<'a>]>,
|
||||
{
|
||||
@@ -192,7 +194,7 @@ where
|
||||
/// .finish();
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn children<C>(self, children: C) -> ElementBuilder<'a, Listeners, Attributes, C>
|
||||
pub fn children<C>(self, children: C) -> ElementBuilder<'a, 'b, Listeners, Attributes, C>
|
||||
where
|
||||
C: 'a + AsRef<[VNode<'a>]>,
|
||||
{
|
||||
@@ -290,17 +292,17 @@ where
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn finish(self) -> VNode<'a> {
|
||||
let children: &'a Children = self.ctx.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.ctx.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.ctx.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.ctx.bump(),
|
||||
self.ctx.bump,
|
||||
self.key,
|
||||
self.tag_name,
|
||||
listeners,
|
||||
@@ -311,8 +313,8 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Attributes, Children>
|
||||
ElementBuilder<'a, bumpalo::collections::Vec<'a, Listener<'a>>, Attributes, Children>
|
||||
impl<'a, 'b, Attributes, Children>
|
||||
ElementBuilder<'a, 'b, bumpalo::collections::Vec<'a, Listener<'a>>, Attributes, Children>
|
||||
where
|
||||
Attributes: 'a + AsRef<[Attribute<'a>]>,
|
||||
Children: 'a + AsRef<[VNode<'a>]>,
|
||||
@@ -355,8 +357,8 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Listeners, Children>
|
||||
ElementBuilder<'a, Listeners, bumpalo::collections::Vec<'a, Attribute<'a>>, Children>
|
||||
impl<'a, 'b, Listeners, Children>
|
||||
ElementBuilder<'a, 'b, Listeners, bumpalo::collections::Vec<'a, Attribute<'a>>, Children>
|
||||
where
|
||||
Listeners: 'a + AsRef<[Listener<'a>]>,
|
||||
Children: 'a + AsRef<[VNode<'a>]>,
|
||||
@@ -414,8 +416,8 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Listeners, Attributes>
|
||||
ElementBuilder<'a, Listeners, Attributes, bumpalo::collections::Vec<'a, VNode<'a>>>
|
||||
impl<'a, 'b, Listeners, Attributes>
|
||||
ElementBuilder<'a, 'b, Listeners, Attributes, bumpalo::collections::Vec<'a, VNode<'a>>>
|
||||
where
|
||||
Listeners: 'a + AsRef<[Listener<'a>]>,
|
||||
Attributes: 'a + AsRef<[Attribute<'a>]>,
|
||||
|
||||
+71
-37
@@ -24,49 +24,90 @@ use bumpalo::Bump;
|
||||
use crate::innerlude::{Listener, ScopeIdx};
|
||||
use serde::{Deserialize, Serialize};
|
||||
/// The `Edit` represents a single modifcation of the renderer tree.
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
/// todo@ jon: allow serde to be optional
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum Edit<'d> {
|
||||
SetText { text: &'d str },
|
||||
SetText {
|
||||
text: &'d str,
|
||||
},
|
||||
RemoveSelfAndNextSiblings {},
|
||||
ReplaceWith,
|
||||
SetAttribute { name: &'d str, value: &'d str },
|
||||
RemoveAttribute { name: &'d str },
|
||||
PushReverseChild { n: u32 },
|
||||
PopPushChild { n: u32 },
|
||||
SetAttribute {
|
||||
name: &'d str,
|
||||
value: &'d str,
|
||||
},
|
||||
RemoveAttribute {
|
||||
name: &'d str,
|
||||
},
|
||||
PushReverseChild {
|
||||
n: u32,
|
||||
},
|
||||
PopPushChild {
|
||||
n: u32,
|
||||
},
|
||||
Pop,
|
||||
AppendChild,
|
||||
CreateTextNode { text: &'d str },
|
||||
CreateElement { tag_name: &'d str },
|
||||
NewEventListener { event_type: &'d str, s: ScopeIdx },
|
||||
UpdateEventListener { event_type: &'d str, s: ScopeIdx },
|
||||
RemoveEventListener { event_type: &'d str },
|
||||
CreateElementNs { tag_name: &'d str, ns: &'d str },
|
||||
SaveChildrenToTemporaries { temp: u32, start: u32, end: u32 },
|
||||
PushChild { n: u32 },
|
||||
PushTemporary { temp: u32 },
|
||||
CreateTextNode {
|
||||
text: &'d str,
|
||||
},
|
||||
CreateElement {
|
||||
tag_name: &'d str,
|
||||
},
|
||||
|
||||
CreateElementNs {
|
||||
tag_name: &'d str,
|
||||
ns: &'d str,
|
||||
},
|
||||
SaveChildrenToTemporaries {
|
||||
temp: u32,
|
||||
start: u32,
|
||||
end: u32,
|
||||
},
|
||||
PushChild {
|
||||
n: u32,
|
||||
},
|
||||
PushTemporary {
|
||||
temp: u32,
|
||||
},
|
||||
InsertBefore,
|
||||
PopPushReverseChild { n: u32 },
|
||||
RemoveChild { n: u32 },
|
||||
SetClass { class_name: &'d str },
|
||||
PopPushReverseChild {
|
||||
n: u32,
|
||||
},
|
||||
RemoveChild {
|
||||
n: u32,
|
||||
},
|
||||
SetClass {
|
||||
class_name: &'d str,
|
||||
},
|
||||
|
||||
// push a known node on to the stack
|
||||
TraverseToKnown { node: ScopeIdx },
|
||||
TraverseToKnown {
|
||||
node: ScopeIdx,
|
||||
},
|
||||
|
||||
// Add the current top of the stack to the known nodes
|
||||
MakeKnown { node: ScopeIdx },
|
||||
MakeKnown {
|
||||
node: ScopeIdx,
|
||||
},
|
||||
|
||||
// Remove the current top of the stack from the known nodes
|
||||
RemoveKnown,
|
||||
|
||||
NewListener {
|
||||
event: &'d str,
|
||||
scope: ScopeIdx,
|
||||
id: usize,
|
||||
},
|
||||
UpdateListener {
|
||||
event: &'d str,
|
||||
scope: ScopeIdx,
|
||||
id: usize,
|
||||
},
|
||||
RemoveListener {
|
||||
event: &'d str,
|
||||
},
|
||||
// NewListener { event: &'d str, id: usize, s: ScopeIdx },
|
||||
}
|
||||
|
||||
pub type EditList<'src> = Vec<Edit<'src>>;
|
||||
@@ -318,10 +359,7 @@ impl<'a> EditMachine<'a> {
|
||||
|
||||
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: scope,
|
||||
});
|
||||
self.emitter.push(Edit::NewListener { event, scope, id });
|
||||
// log::debug!("emit: new_event_listener({:?})", listener);
|
||||
}
|
||||
|
||||
@@ -332,16 +370,12 @@ impl<'a> EditMachine<'a> {
|
||||
return;
|
||||
}
|
||||
|
||||
self.emitter.push(Edit::NewEventListener {
|
||||
event_type: event,
|
||||
s: scope,
|
||||
});
|
||||
self.emitter.push(Edit::NewListener { event, scope, id });
|
||||
}
|
||||
|
||||
pub fn remove_event_listener(&mut self, event: &'a str) {
|
||||
debug_assert!(self.traversal_is_committed());
|
||||
self.emitter
|
||||
.push(Edit::RemoveEventListener { event_type: event });
|
||||
self.emitter.push(Edit::RemoveListener { event });
|
||||
// debug!("emit: remove_event_listener({:?})", event);
|
||||
}
|
||||
|
||||
|
||||
@@ -277,11 +277,15 @@ mod tests {
|
||||
use crate::prelude::format_args_f;
|
||||
|
||||
static ListenerTest: FC<()> = |ctx, props| {
|
||||
ctx.render(html! {
|
||||
<div onclick={|_| println!("Hell owlrld")}>
|
||||
"hello"
|
||||
</div>
|
||||
ctx.render(move |c| {
|
||||
//
|
||||
builder::ElementBuilder::new(c, "div").finish()
|
||||
})
|
||||
// ctx.render(html! {
|
||||
// <div onclick={|_| println!("Hell owlrld")}>
|
||||
// "hello"
|
||||
// </div>
|
||||
// })
|
||||
};
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in new issue
Block a user