Skip to main content

euv_core/renderer/render/
fn.rs

1use crate::*;
2
3/// Mounts the given virtual DOM tree to a specific element matched by a CSS selector.
4///
5/// Supported selector syntax:
6/// - `"#id"` — select by element ID
7/// - `".class"` — select by class name (uses the first match)
8/// - `"tag"` — select by tag name (uses the first match)
9///
10/// # Arguments
11///
12/// - `&str` - A CSS selector string to locate the target element.
13/// - `FnOnce() -> VirtualNode + 'static` - A closure that returns the virtual DOM tree to render.
14///
15/// # Panics
16///
17/// Panics if no global `window` or `document` exists, or if the selector does not match any element.
18pub fn mount<F>(selector: &str, render_fn: F)
19where
20    F: FnOnce() -> VirtualNode,
21{
22    init_event_delegation();
23    let window: Window = window().expect("no global window exists");
24    let document: Document = window.document().expect("should have a document");
25    let target: Element = if selector == "body" {
26        document.body().expect("document should have a body").into()
27    } else if let Some(id) = selector.strip_prefix('#') {
28        document
29            .get_element_by_id(id)
30            .unwrap_or_else(|| panic!("no element found with id '{}'", id))
31    } else if let Some(class) = selector.strip_prefix('.') {
32        document
33            .get_elements_by_class_name(class)
34            .item(0)
35            .unwrap_or_else(|| panic!("no element found with class '{}'", class))
36    } else {
37        document
38            .get_elements_by_tag_name(selector)
39            .item(0)
40            .unwrap_or_else(|| panic!("no element found with tag '{}'", selector))
41    };
42    let mut renderer: Renderer = Renderer::new(target);
43    let vnode: VirtualNode = render_fn();
44    renderer.render(vnode);
45}