#![deny(missing_debug_implementations)]
mod dom_node;
#[cfg(feature = "hydrate")]
pub mod hydrate;
#[cfg(feature = "hydrate")]
mod hydrate_node;
#[cfg(feature = "ssr")]
mod ssr_node;
use std::any::{Any, TypeId};
pub use dom_node::*;
#[cfg(feature = "hydrate")]
pub use hydrate_node::*;
#[cfg(feature = "ssr")]
pub use ssr_node::*;
use sycamore_core::generic_node::GenericNode;
use sycamore_reactive::*;
use wasm_bindgen::prelude::*;
use web_sys::Event;
pub trait Html: GenericNode<EventType = Event, PropertyType = JsValue> {
const IS_BROWSER: bool;
}
pub fn from_web_sys<G: Html>(node: web_sys::Node) -> G {
let type_id = TypeId::of::<G>();
if TypeId::of::<DomNode>() == type_id {
let node = DomNode::from_web_sys(node);
return (&node as &dyn Any).downcast_ref().cloned().unwrap();
}
#[cfg(feature = "hydrate")]
if TypeId::of::<HydrateNode>() == type_id {
let node = HydrateNode::from_web_sys(node);
return (&node as &dyn Any).downcast_ref().cloned().unwrap();
}
panic!("expected GenericNode to either be a DomNode or a HydrateNode");
}
pub fn on_mount<'a>(cx: Scope<'a>, f: impl Fn() + 'a) {
if cfg!(target_arch = "wasm32") {
let scope_status = use_scope_status(cx);
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_name = "queueMicrotask")]
fn queue_microtask(f: &Closure<dyn Fn()>);
}
let f: Box<dyn Fn()> = Box::new(f);
let f_extended: Box<dyn Fn() + 'static> = unsafe { std::mem::transmute(f) };
let cb = move || {
if *scope_status.get() {
f_extended();
}
};
let boxed: Box<dyn Fn()> = Box::new(cb);
let closure = create_ref(cx, Closure::wrap(boxed));
queue_microtask(closure);
}
}