use super::*;
pub fn render(view: impl FnOnce() -> View) {
render_to(view, &document().body().unwrap());
}
pub fn render_to(view: impl FnOnce() -> View, parent: &web_sys::Node) {
let _ = create_root(|| render_in_scope(view, parent));
}
pub fn render_in_scope(view: impl FnOnce() -> View, parent: &web_sys::Node) {
if is_ssr!() {
panic!("`render_in_scope` is not available in SSR mode");
} else {
IS_HYDRATING.set(false);
let nodes = view().nodes;
for node in nodes {
parent.append_child(node.as_web_sys()).unwrap();
}
}
}
#[cfg(feature = "hydrate")]
pub fn hydrate(view: impl FnOnce() -> View) {
hydrate_to(view, &document().body().unwrap());
}
#[cfg(feature = "hydrate")]
pub fn hydrate_to(view: impl FnOnce() -> View, parent: &web_sys::Node) {
let _ = create_root(|| hydrate_in_scope(view, parent));
}
#[cfg(feature = "hydrate")]
pub fn hydrate_in_scope(view: impl FnOnce() -> View, parent: &web_sys::Node) {
is_ssr! {
let _ = view;
let _ = parent;
panic!("`hydrate_in_scope` is not available in SSR mode");
}
is_not_ssr! {
let mode = js_sys::Reflect::get(&window(), &"__sycamore_ssr_mode".into()).unwrap();
let mode = if mode.is_undefined() {
SsrMode::Sync
} else if mode == "blocking" {
SsrMode::Blocking
} else if mode == "streaming" {
SsrMode::Streaming
} else {
panic!("invalid SSR mode {mode:?}")
};
let existing_nodes = parent
.unchecked_ref::<web_sys::Element>()
.query_selector_all("[data-hk]")
.unwrap();
HYDRATE_NODES.with(|nodes| {
let mut nodes = nodes.borrow_mut();
let len = existing_nodes.length();
for i in 0..len {
let node = existing_nodes.get(i).unwrap();
let hk = node.unchecked_ref::<web_sys::Element>().get_attribute("data-hk").unwrap();
let key = HydrationKey::parse(&hk).expect("could not parse hydration key");
let node = HydrateNode::from_web_sys(node);
nodes.insert(key, node);
}
});
IS_HYDRATING.set(true);
provide_context(mode);
provide_context(HydrationRegistry::new());
let nodes = view().nodes;
let mut parent = HydrateNode::from_web_sys(parent.clone());
for node in nodes {
parent.append_child(node);
}
#[cfg(not(feature = "suspense"))]
IS_HYDRATING.set(false);
#[cfg(feature = "suspense")]
create_effect(|| {
if IS_HYDRATING.get() && !sycamore_futures::use_is_loading_global() {
IS_HYDRATING.set(false);
}
});
}
}