use wasm_bindgen::JsCast;
use web_sys::Element;
use std::cell::RefCell;
use std::collections::HashMap;
use crate::dom::lifecycle;
use super::ownership;
use super::lifecycle as lc;
thread_local! {
static DISPATCH: RefCell<HashMap<String, fn(Element)>> = RefCell::new(HashMap::new());
}
pub fn register(group: &str, init_fn: fn(Element)) {
DISPATCH.with(|d| {
d.borrow_mut().insert(group.to_string(), init_fn);
});
}
fn dispatch(group: &str, el: Element) {
if let Some(uid) = el.get_attribute("data-rs-uid") {
ownership::register(&uid, None);
lc::set_state(&uid, lc::LifecycleState::Mount);
}
DISPATCH.with(|d| {
if let Some(f) = d.borrow().get(group) {
f(el.clone());
}
});
if let Some(uid) = el.get_attribute("data-rs-uid") {
lc::set_state(&uid, lc::LifecycleState::Active);
}
}
pub fn init_subtree(root: &Element) {
if let Some(group) = root.get_attribute("data-rs-interaction") {
if lifecycle::init_guard(root) {
dispatch(&group, root.clone());
}
}
let Ok(nodes) = root.query_selector_all("[data-rs-interaction]") else { return };
for i in 0..nodes.length() {
let Some(raw) = nodes.item(i) else { continue };
let Ok(el) = raw.dyn_into::<Element>() else { continue };
if !el.is_connected() { continue }
let Some(group) = el.get_attribute("data-rs-interaction") else { continue };
if lifecycle::init_guard(&el) {
dispatch(&group, el);
}
}
}
pub fn init_document() {
let Some(doc) = web_sys::window().and_then(|w| w.document()) else { return };
let Some(body) = doc.body() else { return };
let body_el: Element = body.unchecked_into();
init_subtree(&body_el);
}
pub fn reinit_subtree(root: &Element) {
let Ok(nodes) = root.query_selector_all("[data-rs-initialized]") else { return };
for i in 0..nodes.length() {
let Some(raw) = nodes.item(i) else { continue };
let Ok(el) = raw.dyn_into::<Element>() else { continue };
let _ = el.set_attribute("data-rs-reinit", "");
if let Some(uid) = el.get_attribute("data-rs-uid") {
lc::set_state(&uid, lc::LifecycleState::Replay);
}
}
init_subtree(root);
}