mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-22 20:23:09 +00:00
WIP: moving to CbIdx as serializable event system
This commit is contained in:
parent
e4b1f6ea0d
commit
e840f472fa
9 changed files with 160 additions and 200 deletions
|
@ -16,11 +16,9 @@ static Example: FC<()> = |ctx| {
|
|||
|
||||
ctx.view(html! {
|
||||
<div>
|
||||
<h1> "Hello, {value}" </h1>
|
||||
<button onclick={move |_| set_value("world!")}> "?" </button>
|
||||
<button onclick={move |_| set_value("Dioxus 🎉")}> "?" </button>
|
||||
<div>
|
||||
<h1> "Hello, {value}" </h1>
|
||||
</div>
|
||||
</div>
|
||||
})
|
||||
};
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
# Project: Web-View 🤲 🍨
|
||||
> Proof of concept: stream render edits from server to client
|
||||
- [x] Prove that the diffing and patching framework can support patch streaming
|
||||
|
||||
|
||||
|
||||
# Project: Live-View 🤲 🍨
|
||||
|
@ -8,6 +6,7 @@
|
|||
|
||||
|
||||
# Project: Sanitization (TBD)
|
||||
> Improve code health
|
||||
- [ ] (Macro) Clippy sanity for html macro
|
||||
- [ ] (Macro) Error sanitization
|
||||
|
||||
|
@ -22,13 +21,19 @@
|
|||
# Project: Concurrency (TBD)
|
||||
> Ensure the concurrency model works well, play with lifetimes to check if it can be multithreaded + halted
|
||||
|
||||
|
||||
# Project: Web-View 🤲 🍨
|
||||
> Proof of concept: stream render edits from server to client
|
||||
- [x] Prove that the diffing and patching framework can support patch streaming
|
||||
|
||||
# Project: Web_sys renderer (TBD)
|
||||
- [ ] (Web) Web-sys renderer and web tests
|
||||
- [x] WebSys edit interpreter
|
||||
- [ ] Event system using async channels
|
||||
|
||||
# Project: String Render (TBD)
|
||||
> Implement a light-weight string renderer with basic caching
|
||||
- [ ] (SSR) Implement stateful 3rd party string renderer
|
||||
- [ ] (Macro) Make VText nodes automatically capture and format IE allow "Text is {blah}" in place of {format!("Text is {}",blah)}
|
||||
- [x] (Macro) Make VText nodes automatically capture and format IE allow "Text is {blah}"
|
||||
|
||||
# Project: Hooks + Context + Subscriptions (TBD)
|
||||
> Implement the foundations for state management
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
use bumpalo::Bump;
|
||||
|
||||
use crate::innerlude::Listener;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
/// The `Edit` represents a single modifcation of the renderer tree.
|
||||
///
|
||||
///
|
||||
|
@ -33,7 +33,7 @@ use crate::innerlude::Listener;
|
|||
///
|
||||
///
|
||||
/// todo@ jon: allow serde to be optional
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum Edit<'d> {
|
||||
SetText { text: &'d str },
|
||||
|
@ -47,8 +47,8 @@ pub enum Edit<'d> {
|
|||
AppendChild,
|
||||
CreateTextNode { text: &'d str },
|
||||
CreateElement { tag_name: &'d str },
|
||||
NewEventListener { event_type: &'d str, a: u32, b: u32 },
|
||||
UpdateEventListener { event_type: &'d str, a: u32, b: u32 },
|
||||
NewEventListener { event_type: &'d str, idx: CbIdx },
|
||||
UpdateEventListener { event_type: &'d str, idx: CbIdx },
|
||||
RemoveEventListener { event_type: &'d str },
|
||||
CreateElementNs { tag_name: &'d str, ns: &'d str },
|
||||
SaveChildrenToTemporaries { temp: u32, start: u32, end: u32 },
|
||||
|
@ -60,6 +60,26 @@ pub enum Edit<'d> {
|
|||
SetClass { class_name: &'d str },
|
||||
}
|
||||
|
||||
/// Re-export a cover over generational ID for libraries that don't need it
|
||||
/// We can go back and forth between the two via methods on GI
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
|
||||
pub struct CbIdx {
|
||||
gi_id: usize,
|
||||
gi_gen: u64,
|
||||
listener_idx: usize,
|
||||
}
|
||||
|
||||
impl CbIdx {
|
||||
pub fn from_gi_index(index: generational_arena::Index, listener_idx: usize) -> Self {
|
||||
let (gi_id, gi_gen) = index.into_raw_parts();
|
||||
Self {
|
||||
gi_id,
|
||||
gi_gen,
|
||||
listener_idx,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type EditList<'src> = Vec<Edit<'src>>;
|
||||
|
||||
pub struct EditMachine<'src> {
|
||||
|
@ -306,38 +326,41 @@ impl<'a> EditMachine<'a> {
|
|||
self.forcing_new_listeners = previous;
|
||||
}
|
||||
|
||||
pub fn new_event_listener(&mut self, listener: &Listener) {
|
||||
pub fn new_event_listener(&mut self, event: &'a str, idx: CbIdx) {
|
||||
debug_assert!(self.traversal_is_committed());
|
||||
// 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.push(Edit::NewEventListener {
|
||||
event_type: listener.event.into(),
|
||||
a,
|
||||
b,
|
||||
event_type: event,
|
||||
idx,
|
||||
});
|
||||
// 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, listener: &Listener) {
|
||||
pub fn update_event_listener(&mut self, event: &'a str, idx: CbIdx) {
|
||||
debug_assert!(self.traversal_is_committed());
|
||||
|
||||
if self.forcing_new_listeners {
|
||||
self.new_event_listener(listener);
|
||||
self.new_event_listener(event, idx);
|
||||
return;
|
||||
}
|
||||
|
||||
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.push(Edit::NewEventListener {
|
||||
event_type: event,
|
||||
idx,
|
||||
});
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,9 +44,9 @@ pub struct Context<'src> {
|
|||
}
|
||||
|
||||
impl<'a> Context<'a> {
|
||||
pub fn props<P>() -> &'a P {
|
||||
todo!()
|
||||
}
|
||||
// pub fn props<P>() -> &'a P {
|
||||
// todo!()
|
||||
// }
|
||||
|
||||
// impl<'a, PropType> Context<'a, PropType> {
|
||||
/// Access the children elements passed into the component
|
||||
|
@ -56,7 +56,8 @@ impl<'a> Context<'a> {
|
|||
|
||||
/// Create a subscription that schedules a future render for the reference component
|
||||
pub fn schedule_update(&self) -> impl Fn() -> () {
|
||||
todo!("Subscription API is not ready yet");
|
||||
// log::debug!()
|
||||
// todo!("Subscription API is not ready yet");
|
||||
|| {}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ use fxhash::{FxHashMap, FxHashSet};
|
|||
use generational_arena::Index;
|
||||
|
||||
use crate::{
|
||||
changelist::{Edit, EditList, EditMachine},
|
||||
changelist::{CbIdx, Edit, EditList, EditMachine},
|
||||
innerlude::{Attribute, Listener, Scope, VElement, VNode, VText},
|
||||
virtual_dom::LifecycleEvent,
|
||||
};
|
||||
|
@ -61,16 +61,20 @@ pub struct DiffMachine<'a> {
|
|||
immediate_queue: Vec<Index>,
|
||||
diffed: FxHashSet<Index>,
|
||||
need_to_diff: FxHashSet<Index>,
|
||||
|
||||
// Current scopes we're comparing
|
||||
current_idx: Option<generational_arena::Index>,
|
||||
}
|
||||
|
||||
impl<'a> DiffMachine<'a> {
|
||||
pub fn new(bump: &'a Bump) -> Self {
|
||||
log::debug!("starsting diff machine");
|
||||
log::debug!("starting diff machine");
|
||||
Self {
|
||||
change_list: EditMachine::new(bump),
|
||||
immediate_queue: Vec::new(),
|
||||
diffed: FxHashSet::default(),
|
||||
need_to_diff: FxHashSet::default(),
|
||||
current_idx: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,8 +82,17 @@ impl<'a> DiffMachine<'a> {
|
|||
self.change_list.emitter
|
||||
}
|
||||
|
||||
pub fn diff_node(&mut self, old: &VNode<'a>, new: &VNode<'a>) {
|
||||
pub fn diff_node(
|
||||
&mut self,
|
||||
old: &VNode<'a>,
|
||||
new: &VNode<'a>,
|
||||
scope: Option<generational_arena::Index>,
|
||||
) {
|
||||
log::debug!("Diffing nodes");
|
||||
|
||||
// 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.
|
||||
|
@ -222,6 +235,7 @@ impl<'a> DiffMachine<'a> {
|
|||
todo!("Suspended components not currently available")
|
||||
}
|
||||
}
|
||||
self.current_idx = None;
|
||||
}
|
||||
|
||||
// Diff event listeners between `old` and `new`.
|
||||
|
@ -237,16 +251,20 @@ impl<'a> DiffMachine<'a> {
|
|||
}
|
||||
|
||||
'outer1: for new_l in new {
|
||||
unsafe {
|
||||
// unsafe {
|
||||
// Safety relies on removing `new_l` from the registry manually at
|
||||
// the end of its lifetime. This happens below in the `'outer2`
|
||||
// loop, and elsewhere in diffing when removing old dom trees.
|
||||
// registry.add(new_l);
|
||||
}
|
||||
// }
|
||||
|
||||
for old_l in old {
|
||||
for (l_idx, old_l) in old.iter().enumerate() {
|
||||
if new_l.event == old_l.event {
|
||||
self.change_list.update_event_listener(new_l);
|
||||
let event_type = new_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);
|
||||
}
|
||||
continue 'outer1;
|
||||
}
|
||||
}
|
||||
|
@ -507,7 +525,7 @@ impl<'a> DiffMachine<'a> {
|
|||
|
||||
self.change_list.go_to_sibling(i);
|
||||
|
||||
self.diff_node(old, new);
|
||||
self.diff_node(old, new, self.current_idx);
|
||||
|
||||
shared_prefix_count += 1;
|
||||
}
|
||||
|
@ -705,7 +723,7 @@ impl<'a> DiffMachine<'a> {
|
|||
// [... parent]
|
||||
self.change_list.go_down_to_temp_child(temp);
|
||||
// [... parent last]
|
||||
self.diff_node(&old[old_index], last);
|
||||
self.diff_node(&old[old_index], last, self.current_idx);
|
||||
|
||||
if new_index_is_in_lis.contains(&last_index) {
|
||||
// Don't move it, since it is already where it needs to be.
|
||||
|
@ -758,7 +776,7 @@ impl<'a> DiffMachine<'a> {
|
|||
// [... parent new_child]
|
||||
}
|
||||
|
||||
self.diff_node(&old[old_index], new_child);
|
||||
self.diff_node(&old[old_index], new_child, self.current_idx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -789,8 +807,7 @@ impl<'a> DiffMachine<'a> {
|
|||
|
||||
for (i, (old_child, new_child)) in old.iter().zip(new.iter()).enumerate() {
|
||||
self.change_list.go_to_sibling(new_shared_suffix_start + i);
|
||||
|
||||
self.diff_node(old_child, new_child);
|
||||
self.diff_node(old_child, new_child, self.current_idx);
|
||||
}
|
||||
|
||||
// [... parent]
|
||||
|
@ -818,7 +835,7 @@ impl<'a> DiffMachine<'a> {
|
|||
// [... parent prev_child]
|
||||
self.change_list.go_to_sibling(i);
|
||||
// [... parent this_child]
|
||||
self.diff_node(old_child, new_child);
|
||||
self.diff_node(old_child, new_child, self.current_idx);
|
||||
}
|
||||
|
||||
match old.len().cmp(&new.len()) {
|
||||
|
@ -880,12 +897,21 @@ impl<'a> DiffMachine<'a> {
|
|||
self.change_list.create_element(tag_name);
|
||||
}
|
||||
|
||||
for l in listeners {
|
||||
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");
|
||||
}
|
||||
});
|
||||
// for l in listeners {
|
||||
// unsafe {
|
||||
// registry.add(l);
|
||||
// }
|
||||
self.change_list.new_event_listener(l);
|
||||
}
|
||||
// }
|
||||
|
||||
for attr in attributes {
|
||||
self.change_list
|
||||
|
|
|
@ -96,6 +96,7 @@ pub(crate) mod innerlude {
|
|||
pub(crate) use crate::virtual_dom::VirtualDom;
|
||||
pub(crate) use nodes::*;
|
||||
|
||||
pub use crate::changelist::CbIdx;
|
||||
// pub use nodes::iterables::IterableNodes;
|
||||
/// This type alias is an internal way of abstracting over the static functions that represent components.
|
||||
|
||||
|
@ -151,119 +152,3 @@ pub mod prelude {
|
|||
|
||||
pub use crate::hooks::*;
|
||||
}
|
||||
|
||||
// #[macro_use]
|
||||
// extern crate dioxus_core_macro;
|
||||
|
||||
// #[macro_use]
|
||||
// extern crate fstrings;
|
||||
// pub use dioxus_core_macro::format_args_f;
|
||||
// macro_rules! mk_macros {( @with_dollar![$dol:tt]=>
|
||||
// $(
|
||||
// #[doc = $doc_string:literal]
|
||||
// $printlnf:ident
|
||||
// => $println:ident!($($stream:ident,)? ...)
|
||||
// ,
|
||||
// )*
|
||||
// ) => (
|
||||
// $(
|
||||
// #[doc = $doc_string]
|
||||
// #[macro_export]
|
||||
// macro_rules! $printlnf {(
|
||||
// $($dol $stream : expr,)? $dol($dol args:tt)*
|
||||
// ) => (
|
||||
// $println!($($dol $stream,)? "{}", format_args_f!($dol($dol args)*))
|
||||
// )}
|
||||
// )*
|
||||
// )}
|
||||
|
||||
// mk_macros! { @with_dollar![$]=>
|
||||
// #[doc = "Like [`print!`](https://doc.rust-lang.org/std/macro.print.html), but with basic f-string interpolation."]
|
||||
// print_f
|
||||
// => print!(...)
|
||||
// ,
|
||||
// #[doc = "Like [`println!`](https://doc.rust-lang.org/std/macro.println.html), but with basic f-string interpolation."]
|
||||
// println_f
|
||||
// => println!(...)
|
||||
// ,
|
||||
// #[doc = "Like [`eprint!`](https://doc.rust-lang.org/std/macro.eprint.html), but with basic f-string interpolation."]
|
||||
// eprint_f
|
||||
// => eprint!(...)
|
||||
// ,
|
||||
// #[doc = "Like [`eprintln!`](https://doc.rust-lang.org/std/macro.eprintln.html), but with basic f-string interpolation."]
|
||||
// eprintln_f
|
||||
// => eprintln!(...)
|
||||
// ,
|
||||
// #[doc = "Like [`format!`](https://doc.rust-lang.org/std/macro.format.html), but with basic f-string interpolation."]
|
||||
// format_f
|
||||
// => format!(...)
|
||||
// ,
|
||||
// #[doc = "Shorthand for [`format_f`]."]
|
||||
// f
|
||||
// => format!(...)
|
||||
// ,
|
||||
// #[doc = "Like [`panic!`](https://doc.rust-lang.org/std/macro.panic.html), but with basic f-string interpolation."]
|
||||
// panic_f
|
||||
// => panic!(...)
|
||||
// ,
|
||||
// #[doc = "Like [`unreachable!`](https://doc.rust-lang.org/std/macro.unreachable.html), but with basic f-string interpolation."]
|
||||
// unreachable_f
|
||||
// => unreachable!(...)
|
||||
// ,
|
||||
// #[doc = "Like [`unimplemented!`](https://doc.rust-lang.org/std/macro.unimplemented.html), but with basic f-string interpolation."]
|
||||
// unimplemented_f
|
||||
// => unimplemented!(...)
|
||||
// ,
|
||||
// #[doc = "Like [`write!`](https://doc.rust-lang.org/std/macro.write.html), but with basic f-string interpolation."]
|
||||
// write_f
|
||||
// => write!(stream, ...)
|
||||
// ,
|
||||
// #[doc = "Like [`writeln!`](https://doc.rust-lang.org/std/macro.writeln.html), but with basic f-string interpolation."]
|
||||
// writeln_f
|
||||
// => writeln!(stream, ...)
|
||||
// ,
|
||||
// }
|
||||
/// Like the `format!` macro for creating `std::string::String`s but for
|
||||
/// `bumpalo::collections::String`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use bumpalo::Bump;
|
||||
///
|
||||
/// let b = Bump::new();
|
||||
///
|
||||
/// let who = "World";
|
||||
/// let s = bumpalo::format!(in &b, "Hello, {}!", who);
|
||||
/// assert_eq!(s, "Hello, World!")
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! ifmt {
|
||||
( in $bump:expr; $fmt:literal;) => {{
|
||||
use bumpalo::core_alloc::fmt::Write;
|
||||
use $crate::prelude::bumpalo;
|
||||
let bump = $bump;
|
||||
let mut s = bumpalo::collections::String::new_in(bump);
|
||||
let args = $crate::prelude::format_args_f!($fmt);
|
||||
s.write_fmt(args);
|
||||
s
|
||||
}};
|
||||
}
|
||||
// ( in $bump:expr; $fmt:expr; ) => {
|
||||
// $println!("{}", format_args_f!($dol($dol args)*))
|
||||
|
||||
// write!(&mut s, println!("{}", args));
|
||||
// let _ = $crate::write_f!(&mut s, $fmt);
|
||||
// s
|
||||
// use fstrings::*;
|
||||
// $crate::ifmt!(in $bump, $fmt)
|
||||
// };
|
||||
|
||||
#[test]
|
||||
fn macro_test() {
|
||||
let w = 123;
|
||||
let world = &w;
|
||||
// let g = format_args_f!("Hello {world}");
|
||||
|
||||
// dbg!(g);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ log = "0.4.14"
|
|||
fxhash = "0.2.1"
|
||||
pretty_env_logger = "0.4.0"
|
||||
console_error_panic_hook = "0.1.6"
|
||||
generational-arena = "0.2.8"
|
||||
# html-validation = { path = "../html-validation", version = "0.1.1" }
|
||||
|
||||
[dependencies.web-sys]
|
||||
|
|
|
@ -23,16 +23,3 @@ static Example: FC<()> = |ctx, props| {
|
|||
</div>
|
||||
})
|
||||
};
|
||||
|
||||
struct ItemProps {
|
||||
name: String,
|
||||
birthdate: String,
|
||||
}
|
||||
static Item: FC<ItemProps> = |ctx, ItemProps { name, birthdate }| {
|
||||
ctx.view(html! {
|
||||
<div>
|
||||
<p>"{name}"</p>
|
||||
<p>"{birthdate}"</p>
|
||||
</div>
|
||||
})
|
||||
};
|
||||
|
|
|
@ -20,22 +20,50 @@ impl std::fmt::Debug for RootCallback {
|
|||
pub(crate) struct PatchMachine {
|
||||
pub(crate) stack: Stack,
|
||||
|
||||
pub(crate) root: Element,
|
||||
|
||||
pub(crate) temporaries: FxHashMap<u32, Node>,
|
||||
|
||||
pub(crate) document: Document,
|
||||
|
||||
pub(crate) events: EventDelegater,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct EventDelegater {
|
||||
root: Element,
|
||||
|
||||
temporaries: FxHashMap<u32, Node>,
|
||||
|
||||
// callback: RootCallback,
|
||||
// callback: Option<Closure<dyn Fn(EventTrigger)>>,
|
||||
document: Document,
|
||||
|
||||
// every callback gets a monotomically increasing callback ID
|
||||
callback_id: usize,
|
||||
|
||||
// map of listener types to number of those listeners
|
||||
listeners: FxHashMap<&'static str, (usize, Closure<dyn Fn()>)>,
|
||||
|
||||
// Map of callback_id to component index and listener id
|
||||
callback_map: FxHashMap<usize, (usize, usize)>,
|
||||
}
|
||||
|
||||
// templates: FxHashMap<CacheId, Node>,
|
||||
impl EventDelegater {
|
||||
pub fn new(root: Element) -> Self {
|
||||
Self {
|
||||
root,
|
||||
callback_id: 0,
|
||||
listeners: FxHashMap::default(),
|
||||
callback_map: FxHashMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_listener(
|
||||
&mut self,
|
||||
event: &'static str,
|
||||
gi: generational_arena::Index,
|
||||
listener_id: usize,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
// callback: RootCallback,
|
||||
// callback: Option<Closure<dyn Fn(EventTrigger)>>,
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Stack {
|
||||
|
@ -85,16 +113,14 @@ impl PatchMachine {
|
|||
.expect("must have access to the Document");
|
||||
|
||||
// attach all listeners to the container element
|
||||
let events = EventDelegater::new(root.clone());
|
||||
|
||||
// templates: Default::default(),
|
||||
Self {
|
||||
root,
|
||||
events,
|
||||
stack: Stack::with_capacity(20),
|
||||
temporaries: Default::default(),
|
||||
// callback: None,
|
||||
document,
|
||||
callback_id: 0,
|
||||
callback_map: FxHashMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,7 +319,11 @@ impl PatchMachine {
|
|||
}
|
||||
|
||||
// 11
|
||||
Edit::NewEventListener { event_type, a, b } => {
|
||||
Edit::NewEventListener {
|
||||
event_type,
|
||||
idx: a,
|
||||
b,
|
||||
} => {
|
||||
// attach the correct attributes to the element
|
||||
// these will be used by accessing the event's target
|
||||
// This ensures we only ever have one handler attached to the root, but decide
|
||||
|
@ -304,16 +334,20 @@ impl PatchMachine {
|
|||
let el = el
|
||||
.dyn_ref::<Element>()
|
||||
.expect(&format!("not an element: {:?}", el));
|
||||
|
||||
// el.add_event_listener_with_callback(
|
||||
// event_type,
|
||||
// self.callback.as_ref().unwrap().as_ref().unchecked_ref(),
|
||||
// )
|
||||
// .unwrap();
|
||||
|
||||
debug!("adding attributes: {}, {}", a, b);
|
||||
el.set_attribute(&format!("dioxus-a-{}", event_type), &a.to_string())
|
||||
.unwrap();
|
||||
el.set_attribute(&format!("dioxus-b-{}", event_type), &b.to_string())
|
||||
.unwrap();
|
||||
|
||||
self.events.add_listener(event_type, gi, listener_id)
|
||||
}
|
||||
|
||||
// 12
|
||||
|
|
Loading…
Reference in a new issue