Skip to main content

virtual_node/
velement.rs

1use std::collections::HashMap;
2use std::fmt;
3
4use crate::VirtualNode;
5
6pub use self::attribute_value::*;
7pub use self::special_attributes::*;
8
9mod attribute_value;
10mod special_attributes;
11
12#[derive(PartialEq)]
13pub struct VElement {
14    /// The HTML tag, such as "div"
15    pub tag: String,
16    /// HTML attributes such as id, class, style, etc
17    pub attrs: HashMap<String, AttributeValue>,
18    /// Events that will get added to your real DOM element via `.addEventListener`
19    ///
20    /// Events natively handled in HTML such as onclick, onchange, oninput and others
21    /// can be found in [`VElement.known_events`]
22    #[cfg(feature = "web")]
23    pub events: crate::event::Events,
24    /// The children of this `VirtualNode`. So a <div> <em></em> </div> structure would
25    /// have a parent div and one child, em.
26    pub children: Vec<VirtualNode>,
27    /// See [`SpecialAttributes`]
28    pub special_attributes: SpecialAttributes,
29}
30
31impl VElement {
32    pub fn new<S>(tag: S) -> Self
33    where
34        S: Into<String>,
35    {
36        VElement {
37            tag: tag.into(),
38            attrs: HashMap::new(),
39            #[cfg(feature = "web")]
40            events: crate::event::Events::new(),
41            children: vec![],
42            special_attributes: SpecialAttributes::default(),
43        }
44    }
45}
46
47impl fmt::Debug for VElement {
48    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
49        write!(
50            f,
51            "Element(<{}>, attrs: {:?}, children: {:?})",
52            self.tag, self.attrs, self.children,
53        )
54    }
55}
56
57impl fmt::Display for VElement {
58    // Turn a VElement and all of it's children (recursively) into an HTML string
59    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
60        write!(f, "<{}", self.tag).unwrap();
61
62        for (attr, value) in self.attrs.iter() {
63            match value {
64                AttributeValue::String(value_str) => {
65                    write!(f, r#" {}="{}""#, attr, value_str)?;
66                }
67                AttributeValue::Bool(value_bool) => {
68                    if *value_bool {
69                        write!(f, " {}", attr)?;
70                    }
71                }
72            }
73        }
74
75        write!(f, ">")?;
76
77        for child in self.children.iter() {
78            write!(f, "{}", child.to_string())?;
79        }
80
81        if !html_validation::is_self_closing(&self.tag) {
82            write!(f, "</{}>", self.tag)?;
83        }
84
85        Ok(())
86    }
87}