implement onmounted for the web renderer
This commit is contained in:
1 parent
1aad285853
commit
cb5cb56ad3
2 files changed
+48
-11
No files matched your search
@@ -116,6 +116,10 @@ mod js {
|
||||
export function set_node(id, node) {
|
||||
nodes[id] = node;
|
||||
}
|
||||
export function get_node(id) {
|
||||
console.log(nodes, id);
|
||||
return nodes[id];
|
||||
}
|
||||
export function initilize(root, handler) {
|
||||
listeners.handler = handler;
|
||||
nodes = [root];
|
||||
@@ -166,6 +170,9 @@ mod js {
|
||||
#[wasm_bindgen]
|
||||
pub fn set_node(id: u32, node: Node);
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn get_node(id: u32) -> Node;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn initilize(root: Node, handler: &Function);
|
||||
}
|
||||
|
||||
+41
-11
@@ -10,8 +10,8 @@
|
||||
use dioxus_core::{
|
||||
BorrowedAttributeValue, ElementId, Mutation, Template, TemplateAttribute, TemplateNode,
|
||||
};
|
||||
use dioxus_html::{event_bubbles, CompositionData, FormData};
|
||||
use dioxus_interpreter_js::{save_template, Channel};
|
||||
use dioxus_html::{event_bubbles, CompositionData, FormData, MountedData};
|
||||
use dioxus_interpreter_js::{get_node, save_template, Channel};
|
||||
use futures_channel::mpsc;
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::{any::Any, rc::Rc};
|
||||
@@ -27,6 +27,7 @@ pub struct WebsysDom {
|
||||
templates: FxHashMap<String, u32>,
|
||||
max_template_id: u32,
|
||||
pub(crate) interpreter: Channel,
|
||||
event_channel: mpsc::UnboundedSender<UiEvent>,
|
||||
}
|
||||
|
||||
pub struct UiEvent {
|
||||
@@ -34,7 +35,6 @@ pub struct UiEvent {
|
||||
pub bubbles: bool,
|
||||
pub element: ElementId,
|
||||
pub data: Rc<dyn Any>,
|
||||
pub event: Event,
|
||||
}
|
||||
|
||||
impl WebsysDom {
|
||||
@@ -48,8 +48,9 @@ impl WebsysDom {
|
||||
};
|
||||
let interpreter = Channel::default();
|
||||
|
||||
let handler: Closure<dyn FnMut(&Event)> =
|
||||
Closure::wrap(Box::new(move |event: &web_sys::Event| {
|
||||
let handler: Closure<dyn FnMut(&Event)> = Closure::wrap(Box::new({
|
||||
let event_channel = event_channel.clone();
|
||||
move |event: &web_sys::Event| {
|
||||
let name = event.type_();
|
||||
let element = walk_event_for_id(event);
|
||||
let bubbles = dioxus_html::event_bubbles(name.as_str());
|
||||
@@ -69,10 +70,10 @@ impl WebsysDom {
|
||||
bubbles,
|
||||
element,
|
||||
data,
|
||||
event: event.clone(),
|
||||
});
|
||||
}
|
||||
}));
|
||||
}
|
||||
}));
|
||||
|
||||
dioxus_interpreter_js::initilize(
|
||||
root.clone().unchecked_into(),
|
||||
@@ -85,6 +86,7 @@ impl WebsysDom {
|
||||
interpreter,
|
||||
templates: FxHashMap::default(),
|
||||
max_template_id: 0,
|
||||
event_channel,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,6 +158,8 @@ impl WebsysDom {
|
||||
pub fn apply_edits(&mut self, mut edits: Vec<Mutation>) {
|
||||
use Mutation::*;
|
||||
let i = &mut self.interpreter;
|
||||
// we need to apply the mount events last, so we collect them here
|
||||
let mut to_mount = Vec::new();
|
||||
for edit in &edits {
|
||||
match edit {
|
||||
AppendChildren { id, m } => i.append_children(id.0 as u32, *m as u32),
|
||||
@@ -206,17 +210,43 @@ impl WebsysDom {
|
||||
},
|
||||
SetText { value, id } => i.set_text(id.0 as u32, value),
|
||||
NewEventListener { name, id, .. } => {
|
||||
i.new_event_listener(name, id.0 as u32, event_bubbles(name) as u8);
|
||||
}
|
||||
RemoveEventListener { name, id } => {
|
||||
i.remove_event_listener(name, id.0 as u32, event_bubbles(name) as u8)
|
||||
match *name {
|
||||
// mounted events are fired immediately after the element is mounted.
|
||||
"mounted" => {
|
||||
to_mount.push(*id);
|
||||
}
|
||||
_ => {
|
||||
i.new_event_listener(name, id.0 as u32, event_bubbles(name) as u8);
|
||||
}
|
||||
}
|
||||
}
|
||||
RemoveEventListener { name, id } => match *name {
|
||||
"mounted" => {}
|
||||
_ => {
|
||||
i.remove_event_listener(name, id.0 as u32, event_bubbles(name) as u8);
|
||||
}
|
||||
},
|
||||
Remove { id } => i.remove(id.0 as u32),
|
||||
PushRoot { id } => i.push_root(id.0 as u32),
|
||||
}
|
||||
}
|
||||
edits.clear();
|
||||
i.flush();
|
||||
|
||||
for id in to_mount {
|
||||
let node = get_node(id.0 as u32);
|
||||
if let Some(element) = node.dyn_ref::<Element>() {
|
||||
log::info!("mounted event fired: {}", id.0);
|
||||
let data: MountedData = element.into();
|
||||
let data = Rc::new(data);
|
||||
let _ = self.event_channel.unbounded_send(UiEvent {
|
||||
name: "mounted".to_string(),
|
||||
bubbles: false,
|
||||
element: id,
|
||||
data,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user