skima 0.1.0

Rust structural UI library for web
Documentation
use wasm_bindgen::JsCast;
use web_sys::HtmlElement;

use crate::tree::Tree;
use crate::web::{Markup, WebSys};
use crate::{console_log, render_subtree, subtree};

pub struct Root<M>
where
    M: Markup<WebSys>,
{
    pub(crate) tree: Tree<WebSys>,
    markup: M,
}

impl<M> Root<M>
where
    M: Markup<WebSys>,
{
    pub fn render(markup: M, container: HtmlElement) -> Root<M> {
        let tree = Tree::root(container.unchecked_into());
        console_log!("Render root subtree");

        render_subtree(&markup, &tree);
        Root { markup, tree }
    }

    pub fn ephemeral(markup: M) -> Root<M> {
        let tree = Tree::ephemeral_root();
        console_log!("Render root subtree");

        if !M::has_own_node() {
            panic!("Ephemeral Root requires markup to have an own tree node");
        }

        markup.render(&tree);

        Root { markup, tree }
    }

    pub fn element(&self) -> HtmlElement {
        self.tree.node().clone().unchecked_into()
    }

    pub fn update(&mut self, next: M) {
        let tree = if M::has_own_node() {
            self.tree.children.borrow().first().unwrap().0.clone()
        } else {
            self.tree.clone()
        };

        next.diff(&self.markup, &tree);
        self.markup = next;
    }
}

impl<M> Drop for Root<M>
where
    M: Markup<WebSys>,
{
    fn drop(&mut self) {
        let tree = subtree::<M, _>(&self.tree);

        self.markup.drop(&tree, false);
        self.tree
            .node()
            .unchecked_ref::<HtmlElement>()
            .set_inner_html("");
    }
}