use js_sys::Function;
use wasm_bindgen::JsValue;
use web_sys::{Document, Element, Node};
use crate::component::Component;
use super::EventType;
pub struct DynamicContent {
pub dependencies: Vec<usize>,
pub update_type: usize,
}
#[derive(Clone)]
pub enum RenderedNode {
Node(Node),
Element(Element),
}
impl From<&RenderedNode> for web_sys::Node {
fn from(node: &RenderedNode) -> Self {
use RenderedNode::*;
match node {
Node(node) => node.clone(),
Element(element) => element.clone().into(),
}
}
}
pub struct DomNodeBuildResult {
pub element: Option<RenderedNode>,
pub cache_node: bool,
pub children: Option<Vec<Box<dyn Renderable>>>,
pub dynamic_content: Vec<DynamicContent>,
pub in_place: bool,
}
pub trait Renderable {
fn render(
self: Box<Self>,
document: &Document,
component: &dyn Component,
element: Option<RenderedNode>,
get_event_closure: &mut dyn FnMut(EventType) -> Function,
) -> Result<Option<DomNodeBuildResult>, JsValue>;
}
impl<I> Renderable for I
where
I: IntoIterator<Item = Box<dyn Renderable>>,
{
fn render(
self: Box<Self>,
_document: &Document,
component: &dyn Component,
element: Option<RenderedNode>,
_get_event_closure: &mut dyn FnMut(EventType) -> Function,
) -> Result<Option<DomNodeBuildResult>, JsValue> {
let children = self.into_iter().collect::<Vec<_>>();
Ok(if !children.is_empty() {
Some(DomNodeBuildResult {
element,
cache_node: false,
children: Some(children),
dynamic_content: Vec::new(),
in_place: true,
})
} else {
None
})
}
}