1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//! Provides support for behaviors as defined in the DOM standards. Because the standards
//! refer extensively to classes and mixins, and because Rust does not support either one,
//! this module provides several structures that provide the same behavior but in a Rust-
//! friendly way (using composition instead of inheritance).

use std::sync::{Arc, Weak};

use crate::error::DomError;
use crate::node::raw::element as raw_element;
use crate::node::raw::AnyRawNode;

/// Behavior according to the DOM class called Node
pub struct NodeBehavior {
    /// Reference back up to the raw Node
    node: Weak<dyn AnyRawNode>,

    parent_node: Option<Weak<dyn AnyRawNode>>,
    left_sibling: Option<Weak<dyn AnyRawNode>>,
    right_sibling: Option<Weak<dyn AnyRawNode>>,
    child_nodes: Vec<Arc<dyn AnyRawNode>>,
}

impl NodeBehavior {
    pub(crate) fn new(node: Weak<dyn AnyRawNode>) -> NodeBehavior {
        NodeBehavior {
            node,
            parent_node: None,
            left_sibling: None,
            right_sibling: None,
            child_nodes: Vec::new(),
        }
    }

    pub(crate) fn first_child(&self) -> Option<&Arc<dyn AnyRawNode>> {
        self.child_nodes.first()
    }

    pub(crate) fn last_child(&self) -> Option<&Arc<dyn AnyRawNode>> {
        self.child_nodes.last()
    }

    pub(crate) fn append_child(&mut self, other: Arc<dyn AnyRawNode>) {
        self.child_nodes.push(other)
    }

    pub(crate) fn clone_node(&self) -> Result<Arc<dyn AnyRawNode>, DomError> {
        let raw_node = self
            .node
            .upgrade()
            .ok_or_else(|| DomError::SandboxDropped)?;
        Ok((*raw_node).clone_node())
    }
}

/// Behavior according to the DOM class called Element
pub struct ElementBehavior {
    /// Reference back up to the raw Element
    element: Weak<dyn raw_element::AnyRawElement>,
}

impl ElementBehavior {
    pub(crate) fn new(element: Weak<dyn raw_element::AnyRawElement>) -> ElementBehavior {
        ElementBehavior { element }
    }
}