simi 0.2.1

A framework for building wasm front-end web application in Rust
//! Support for `for` loop
use super::{Element, Node, NodeList, Text};

/// Hosts node_list created by a `for` loop
pub struct NonKeyedFor {
    node_list: NodeList,
}

#[allow(clippy::new_without_default)]
impl NonKeyedFor {
    /// New NonKeyedFor node
    pub fn with_capacity(capacity: usize) -> Self {
        Self {
            node_list: NodeList::with_capacity(capacity),
        }
    }

    /// Mutable reference to self.node_list
    pub fn node_list_mut(&mut self) -> &mut NodeList {
        &mut self.node_list
    }

    /// Create/update a text node,
    /// return a reference to it if it is new
    pub fn text(&mut self, index: usize, value: &impl ToString) -> Option<&Text> {
        self.node_list.text(index, value)
    }

    /// Create/get an element node
    /// Return (Element, is_element_new, element_need_to_be_insert)
    pub fn element(&mut self, index: usize, tag: &str) -> (&mut Element, bool, bool) {
        let len = self.node_list.nodes.len();
        let (new, need_insert) = if len == 0 {
            self.node_list.nodes.push(Node::Element(Element::new(tag)));
            (true, true)
        } else if index >= len {
            match self.node_list.nodes[0] {
                Node::Element(ref e) => {
                    let e = e.start_clone();
                    self.node_list.nodes.push(Node::Element(e));
                }
                _ => panic!("For loop not contains an Element"),
            }
            (
                false, // The element clone from an old element, hence, no need to init static content
                true,
            )
        } else {
            (false, false)
        };
        debug_assert!(index < self.node_list.nodes.len());
        match unsafe { self.node_list.nodes.get_unchecked_mut(index) } {
            Node::Element(e) => (e, new, need_insert),
            _ => panic!("Expect a Node::Element at the given index"),
        }
    }

    // Remove real node from real dom and return the next sibling
    pub(crate) fn remove_and_get_next_sibling(
        &mut self,
        real_parent: &web_sys::Node,
    ) -> Option<web_sys::Node> {
        self.node_list.remove_and_get_next_sibling(real_parent)
    }

    // Remove real node from real dom
    pub(crate) fn remove_real_node(&mut self, real_parent: &web_sys::Node) {
        self.node_list.remove_real_node(real_parent)
    }

    /// Get next sibling of the last node
    pub fn get_next_sibling(&self) -> Option<web_sys::Node> {
        self.node_list.get_next_sibling()
    }

    /// Get first real node
    pub fn get_first_real_node(&self) -> Option<&web_sys::Node> {
        self.node_list.get_first_real_node()
    }

    /// Clone everything except for tracked attributes, and for-loop content
    pub(super) fn clone(&self, _real_parent: &web_sys::Node) -> Self {
        // Content of a for-loop is not cloned
        Self {
            node_list: NodeList::new(),
        }
    }

    /// Start cloning self and all childs
    pub(super) fn start_clone(&self) -> Self {
        Self {
            node_list: NodeList::new(),
        }
    }
}