1use std::{
2 cell::{Ref, RefCell, RefMut},
3 rc::{Rc, Weak},
4};
5
6use indexmap::IndexMap;
7use stardom_nodes::{EventKey, Node, NodeType};
8
9#[derive(Clone, Debug)]
10pub struct NodeRef(Rc<RefCell<Inner>>);
11
12type WeakNode = Weak<RefCell<Inner>>;
13
14#[derive(Debug)]
15struct Inner {
16 parent: Option<WeakNode>,
17 kind: NodeKind,
18}
19
20#[derive(Debug)]
21pub(crate) enum NodeKind {
22 Element {
23 namespace: Option<String>,
24 name: String,
25 attrs: IndexMap<String, String>,
26 children: Vec<NodeRef>,
27 },
28 Fragment(Vec<NodeRef>),
29 Text(String),
30 Raw(String),
31}
32
33impl NodeRef {
34 fn new(kind: NodeKind) -> Self {
35 let inner = Inner { parent: None, kind };
36 Self(Rc::new(RefCell::new(inner)))
37 }
38
39 pub(crate) fn kind(&self) -> Ref<NodeKind> {
40 let inner = self.0.borrow();
41 Ref::map(inner, |inner| &inner.kind)
42 }
43
44 fn kind_mut(&self) -> RefMut<NodeKind> {
45 let inner = self.0.borrow_mut();
46 RefMut::map(inner, |inner| &mut inner.kind)
47 }
48
49 fn children_ref(&self) -> Option<Ref<Vec<Self>>> {
50 let inner = self.0.borrow();
51 Ref::filter_map(inner, |inner| match &inner.kind {
52 NodeKind::Element { children, .. } => Some(children),
53 NodeKind::Fragment(children) => Some(children),
54 _ => None,
55 })
56 .ok()
57 }
58
59 fn children_mut(&self) -> Option<RefMut<Vec<Self>>> {
60 let inner = self.0.borrow_mut();
61 RefMut::filter_map(inner, |inner| match &mut inner.kind {
62 NodeKind::Element { children, .. } => Some(children),
63 NodeKind::Fragment(children) => Some(children),
64 _ => None,
65 })
66 .ok()
67 }
68}
69
70impl Node for NodeRef {
71 fn element(namespace: Option<&str>, name: &str) -> Self {
72 let kind = NodeKind::Element {
73 namespace: namespace.map(str::to_string),
74 name: name.to_string(),
75 attrs: IndexMap::new(),
76 children: vec![],
77 };
78 Self::new(kind)
79 }
80
81 fn text() -> Self {
82 let kind = NodeKind::Text(String::new());
83 Self::new(kind)
84 }
85
86 fn fragment() -> Self {
87 let kind = NodeKind::Fragment(vec![]);
88 Self::new(kind)
89 }
90
91 fn raw() -> Self {
92 let kind = NodeKind::Raw(String::new());
93 Self::new(kind)
94 }
95
96 fn ty(&self) -> NodeType {
97 match &*self.kind() {
98 NodeKind::Element { .. } => NodeType::Element,
99 NodeKind::Fragment(_) => NodeType::Fragment,
100 NodeKind::Text(_) => NodeType::Text,
101 NodeKind::Raw(_) => NodeType::Raw,
102 }
103 }
104
105 fn parent(&self) -> Option<Self> {
106 self.0
107 .borrow()
108 .parent
109 .as_ref()
110 .and_then(Weak::upgrade)
111 .map(NodeRef)
112 }
113
114 fn children(&self) -> Vec<Self> {
115 self.children_ref()
116 .expect("only element and fragment nodes can have children")
117 .clone()
118 }
119
120 fn next_sibling(&self) -> Option<Self> {
121 let parent = self.parent()?;
122 let children = parent.children_ref()?;
123
124 let idx = children.iter().position(|node| node == self)?;
125 children.get(idx + 1).cloned()
126 }
127
128 fn insert(&self, child: &Self, before: Option<&Self>) {
129 let mut children = self
130 .children_mut()
131 .expect("only element and fragment nodes can have children");
132 let idx = if let Some(before) = before {
133 children
134 .iter()
135 .position(|node| node == before)
136 .expect("not a parent of insertion point node")
137 } else {
138 children.len()
139 };
140 children.insert(idx, child.clone());
141
142 child.0.borrow_mut().parent.replace(Rc::downgrade(&self.0));
143 }
144
145 fn remove(&self, child: &Self) {
146 let mut children = self
147 .children_mut()
148 .expect("only element and fragment nodes can have children");
149 let idx = children
150 .iter()
151 .position(|node| node == child)
152 .expect("not a parent of child node");
153 children.remove(idx);
154
155 child.0.borrow_mut().parent.take();
156 }
157
158 fn set_text(&self, content: &str) {
159 match &mut self.0.borrow_mut().kind {
160 NodeKind::Text(text) => {
161 *text = content.to_string();
162 }
163 NodeKind::Raw(raw) => {
164 *raw = content.to_string();
165 }
166 _ => panic!("can only set text content of text or raw nodes"),
167 }
168 }
169
170 fn attr(&self, name: &str) -> Option<String> {
171 if let NodeKind::Element { attrs, .. } = &*self.kind() {
172 attrs.get(name).cloned()
173 } else {
174 panic!("attributes only exist on element nodes");
175 }
176 }
177
178 fn set_attr(&self, name: &str, value: &str) {
179 if let NodeKind::Element { attrs, .. } = &mut *self.kind_mut() {
180 attrs.insert(name.to_string(), value.to_string());
181 } else {
182 panic!("attributes only exist on element nodes");
183 }
184 }
185
186 fn remove_attr(&self, name: &str) {
187 if let NodeKind::Element { attrs, .. } = &mut *self.kind_mut() {
188 attrs.remove(name);
189 } else {
190 panic!("attributes only exist on element nodes");
191 }
192 }
193
194 fn event<E, F>(&self, _event: &E, _f: F)
195 where
196 E: EventKey,
197 F: Fn(E::Event) + 'static,
198 {
199 }
201}
202
203impl PartialEq for NodeRef {
204 fn eq(&self, other: &Self) -> bool {
205 Rc::ptr_eq(&self.0, &other.0)
206 }
207}
208
209impl Eq for NodeRef {}