simi 0.2.1

A framework for building wasm front-end web application in Rust
//! Sub application
use crate::app::{Application, RcMain, SubAppCollection, WeakMain};
use std::any::Any;
use wasm_bindgen::JsCast;

/// Sub app node. This is just for keep the sub app alive. The sub app must render itself.
pub struct SubApp {
    id: u8,
    rc_main: Box<Any>,
}

impl SubApp {
    /// Create new sub app node
    pub fn new<A, B>(id: u8, real_parent: &web_sys::Node, parent_main: WeakMain<A>) -> Self
    where
        A: Application,
        B: Application<Parent = WeakMain<A>>,
    {
        let root: web_sys::Element = real_parent
            .clone()
            .dyn_into()
            .expect("Parent must be an element");
        let rc_main: RcMain<B> = RcMain::start_in(root, parent_main);
        Self {
            id,
            rc_main: Box::new(rc_main),
        }
    }

    /// Is it the given app type?
    pub fn is_same_app<B: Application>(&self, id: u8) -> bool {
        if self.id != id {
            return false;
        }
        self.rc_main.is::<RcMain<B>>()
    }

    /// Search for the sub app with app state is B
    pub fn collect_to<B: Application>(&self, sub_apps: &mut SubAppCollection) {
        if let Some(rc) = self.rc_main.downcast_ref::<RcMain<B>>() {
            sub_apps.set(self.id, rc.to_weak());
        } else {
            log::error!("Wrong app type");
        }
    }

    /// Remove real nodes from real dom
    pub(crate) fn remove_real_node(&mut self, real_parent: &web_sys::Node) {
        // A sub app is required to be the only content in and element, so just set the parent content empty
        real_parent.set_text_content(None);
    }
}