1use std::cell::{Ref, RefCell, RefMut};
2use std::collections::HashMap;
3use std::fmt;
4use std::rc::{Rc, Weak};
5
6use crate::{is_void_element, Html, IterableNodes};
7
8type Link = Rc<RefCell<DomNodeData>>;
10
11type WeakLink = Weak<RefCell<DomNodeData>>;
12
13pub struct DomNode(Link);
15
16pub struct WeakDomNode(WeakLink);
17
18#[derive(Debug, Clone, PartialEq)]
19pub enum DomNodeKind {
20 Text {
21 text: String,
22 },
23 Element {
24 tag: String,
25 attributes: HashMap<String, String>,
26 },
27}
28
29struct DomNodeData {
30 kind: DomNodeKind,
31 parent: Option<WeakLink>,
32 first_child: Option<Link>,
33 last_child: Option<WeakLink>,
34 previous_sibling: Option<WeakLink>,
35 next_sibling: Option<Link>,
36}
37
38impl Clone for DomNode {
40 fn clone(&self) -> Self {
41 DomNode(Rc::clone(&self.0))
42 }
43}
44
45impl PartialEq for DomNode {
46 fn eq(&self, other: &DomNode) -> bool {
47 Rc::ptr_eq(&self.0, &other.0)
48 }
49}
50
51impl fmt::Debug for DomNode {
52 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53 fmt::Debug::fmt(&self.kind(), f)
54 }
55}
56
57impl DomNode {
58 pub fn new(kind: DomNodeKind) -> DomNode {
60 DomNode(Rc::new(RefCell::new(DomNodeData {
61 kind,
62 parent: None,
63 first_child: None,
64 last_child: None,
65 previous_sibling: None,
66 next_sibling: None,
67 })))
68 }
69
70 pub fn create_element(tag: impl Into<String>) -> DomNode {
71 Self::new(DomNodeKind::Element {
72 tag: tag.into(),
73 attributes: HashMap::new(),
74 })
75 }
76
77 pub fn create_element_with_attributes(
78 tag: impl Into<String>,
79 attributes: HashMap<String, String>,
80 ) -> DomNode {
81 Self::new(DomNodeKind::Element {
82 tag: tag.into(),
83 attributes,
84 })
85 }
86
87 pub fn create_text(text: impl Into<String>) -> DomNode {
88 Self::new(DomNodeKind::Text { text: text.into() })
89 }
90
91 pub fn get_attribute(&self, attribute: &str) -> Option<String> {
92 match &*self.kind() {
93 DomNodeKind::Text { .. } => None,
94 DomNodeKind::Element { attributes, .. } => attributes.get(attribute).cloned(),
95 }
96 }
97
98 pub fn set_attribute(&mut self, key: &str, value: &str) {
99 if let DomNodeKind::Element { attributes, .. } = &mut *self.kind_mut() {
100 attributes.insert(key.into(), value.into());
101 }
102 }
103
104 pub fn downgrade(&self) -> WeakDomNode {
106 WeakDomNode(Rc::downgrade(&self.0))
107 }
108
109 pub fn parent(&self) -> Option<DomNode> {
115 Some(DomNode(self.0.borrow().parent.as_ref()?.upgrade()?))
116 }
117
118 pub fn first_child(&self) -> Option<DomNode> {
124 Some(DomNode(self.0.borrow().first_child.as_ref()?.clone()))
125 }
126
127 pub fn last_child(&self) -> Option<DomNode> {
133 Some(DomNode(self.0.borrow().last_child.as_ref()?.upgrade()?))
134 }
135
136 pub fn previous_sibling(&self) -> Option<DomNode> {
142 Some(DomNode(
143 self.0.borrow().previous_sibling.as_ref()?.upgrade()?,
144 ))
145 }
146
147 pub fn next_sibling(&self) -> Option<DomNode> {
153 Some(DomNode(self.0.borrow().next_sibling.as_ref()?.clone()))
154 }
155
156 pub fn kind(&self) -> Ref<'_, DomNodeKind> {
157 Ref::map(self.0.borrow(), |v| &v.kind)
158 }
159
160 pub fn kind_mut(&self) -> RefMut<'_, DomNodeKind> {
161 RefMut::map(self.0.borrow_mut(), |v| &mut v.kind)
162 }
163
164 pub fn ancestors(&self) -> Ancestors {
168 Ancestors(Some(self.clone()))
169 }
170
171 pub fn preceding_siblings(&self) -> PrecedingSiblings {
175 PrecedingSiblings(Some(self.clone()))
176 }
177
178 pub fn following_siblings(&self) -> FollowingSiblings {
182 FollowingSiblings(Some(self.clone()))
183 }
184
185 pub fn children(&self) -> Children {
191 Children {
192 next: self.first_child(),
193 next_back: self.last_child(),
194 }
195 }
196
197 pub fn has_children(&self) -> bool {
203 self.first_child().is_some()
204 }
205
206 pub fn descendants(&self) -> Descendants {
210 Descendants(self.traverse())
211 }
212
213 pub fn traverse(&self) -> Traverse {
215 Traverse {
216 root: self.clone(),
217 next: Some(NodeEdge::Start(self.clone())),
218 next_back: Some(NodeEdge::End(self.clone())),
219 }
220 }
221
222 pub fn sanitize_children(&mut self) {
224 for mut c in self.children() {
225 c.sanitize_children();
226 }
227
228 let should_remove = match &*self.kind() {
230 DomNodeKind::Text { text } if text.is_empty() => true,
231 DomNodeKind::Element { tag, .. } if tag == "p" && self.first_child().is_none() => true,
233 DomNodeKind::Element { tag, .. } if tag == "p" => self.children().all(|c| {
235 if let DomNodeKind::Text { text } = &*c.kind() {
236 text.chars().all(|c| c == ' ')
237 } else {
238 false
239 }
240 }),
241 _ => false,
242 };
243 if should_remove {
244 self.detach();
245 return;
246 }
247
248 match &mut *self.kind_mut() {
249 DomNodeKind::Text { text } if text.chars().all(|c| c == ' ') => *text = " ".into(),
251 _ => {}
252 };
253 }
254
255 pub fn get_elements_by_tag_name(&self, tag: &str) -> Vec<DomNode> {
256 self.descendants()
257 .filter(|d| {
258 if let DomNodeKind::Element { tag: t, .. } = &*d.kind() {
259 if t == tag {
260 return true;
261 }
262 }
263 false
264 })
265 .collect()
266 }
267
268 pub fn get_element_by_id(&self, id: &str) -> Option<DomNode> {
269 self.descendants().find(|d| {
270 if let DomNodeKind::Element { attributes, .. } = &*d.kind() {
271 if let Some(element_id) = attributes.get("id") {
272 return element_id == id;
273 }
274 }
275 false
276 })
277 }
278
279 pub fn inner_text(&self) -> String {
281 let mut text = String::new();
282 for descendant in self.descendants() {
283 if let DomNodeKind::Text { text: t } = &*descendant.kind() {
284 text.push_str(t);
285 }
286 }
287 text
288 }
289
290 pub fn detach(&self) {
296 self.0.borrow_mut().detach();
297 }
298
299 pub fn append_child(&self, new_child: impl Into<IterableNodes>) {
305 let iter: IterableNodes = new_child.into();
306 for c in iter.0 {
307 assert!(*self != c, "a node cannot be appended to itself");
308
309 let mut self_borrow = self.0.borrow_mut();
310 let mut last_child_opt = None;
311 {
312 let mut new_child_borrow = c.0.borrow_mut();
313 new_child_borrow.detach();
314 new_child_borrow.parent = Some(Rc::downgrade(&self.0));
315 if let Some(last_child_weak) = self_borrow.last_child.take() {
316 if let Some(last_child_strong) = last_child_weak.upgrade() {
317 new_child_borrow.previous_sibling = Some(last_child_weak);
318 last_child_opt = Some(last_child_strong);
319 }
320 }
321 self_borrow.last_child = Some(Rc::downgrade(&c.0));
322 }
323
324 if let Some(last_child_strong) = last_child_opt {
325 let mut last_child_borrow = last_child_strong.borrow_mut();
326 debug_assert!(last_child_borrow.next_sibling.is_none());
327 last_child_borrow.next_sibling = Some(c.0);
328 } else {
329 debug_assert!(self_borrow.first_child.is_none());
331 self_borrow.first_child = Some(c.0);
332 }
333 }
334 }
335
336 pub fn prepend(&self, new_child: DomNode) {
342 assert!(*self != new_child, "a node cannot be prepended to itself");
343
344 let mut self_borrow = self.0.borrow_mut();
345 {
346 let mut new_child_borrow = new_child.0.borrow_mut();
347 new_child_borrow.detach();
348 new_child_borrow.parent = Some(Rc::downgrade(&self.0));
349 match self_borrow.first_child.take() {
350 Some(first_child_strong) => {
351 {
352 let mut first_child_borrow = first_child_strong.borrow_mut();
353 debug_assert!(first_child_borrow.previous_sibling.is_none());
354 first_child_borrow.previous_sibling = Some(Rc::downgrade(&new_child.0));
355 }
356 new_child_borrow.next_sibling = Some(first_child_strong);
357 }
358 None => {
359 debug_assert!(self_borrow.first_child.is_none());
360 self_borrow.last_child = Some(Rc::downgrade(&new_child.0));
361 }
362 }
363 }
364 self_borrow.first_child = Some(new_child.0);
365 }
366
367 pub fn insert_after(&self, new_sibling: DomNode) {
373 assert!(
374 *self != new_sibling,
375 "a node cannot be inserted after itself"
376 );
377
378 let mut self_borrow = self.0.borrow_mut();
379 {
380 let mut new_sibling_borrow = new_sibling.0.borrow_mut();
381 new_sibling_borrow.detach();
382 new_sibling_borrow.parent = self_borrow.parent.clone();
383 new_sibling_borrow.previous_sibling = Some(Rc::downgrade(&self.0));
384 match self_borrow.next_sibling.take() {
385 Some(next_sibling_strong) => {
386 {
387 let mut next_sibling_borrow = next_sibling_strong.borrow_mut();
388 debug_assert!({
389 let weak = next_sibling_borrow.previous_sibling.as_ref().unwrap();
390 Rc::ptr_eq(&weak.upgrade().unwrap(), &self.0)
391 });
392 next_sibling_borrow.previous_sibling = Some(Rc::downgrade(&new_sibling.0));
393 }
394 new_sibling_borrow.next_sibling = Some(next_sibling_strong);
395 }
396 None => {
397 if let Some(parent_ref) = self_borrow.parent.as_ref() {
398 if let Some(parent_strong) = parent_ref.upgrade() {
399 let mut parent_borrow = parent_strong.borrow_mut();
400 parent_borrow.last_child = Some(Rc::downgrade(&new_sibling.0));
401 }
402 }
403 }
404 }
405 }
406 self_borrow.next_sibling = Some(new_sibling.0);
407 }
408
409 pub fn insert_before(&self, new_sibling: DomNode) {
415 assert!(
416 *self != new_sibling,
417 "a node cannot be inserted before itself"
418 );
419
420 let mut self_borrow = self.0.borrow_mut();
421 let mut previous_sibling_opt = None;
422 {
423 let mut new_sibling_borrow = new_sibling.0.borrow_mut();
424 new_sibling_borrow.detach();
425 new_sibling_borrow.parent = self_borrow.parent.clone();
426 new_sibling_borrow.next_sibling = Some(self.0.clone());
427 if let Some(previous_sibling_weak) = self_borrow.previous_sibling.take() {
428 if let Some(previous_sibling_strong) = previous_sibling_weak.upgrade() {
429 new_sibling_borrow.previous_sibling = Some(previous_sibling_weak);
430 previous_sibling_opt = Some(previous_sibling_strong);
431 }
432 }
433 self_borrow.previous_sibling = Some(Rc::downgrade(&new_sibling.0));
434 }
435
436 if let Some(previous_sibling_strong) = previous_sibling_opt {
437 let mut previous_sibling_borrow = previous_sibling_strong.borrow_mut();
438 debug_assert!({
439 let rc = previous_sibling_borrow.next_sibling.as_ref().unwrap();
440 Rc::ptr_eq(rc, &self.0)
441 });
442 previous_sibling_borrow.next_sibling = Some(new_sibling.0);
443 } else {
444 if let Some(parent_ref) = self_borrow.parent.as_ref() {
446 if let Some(parent_strong) = parent_ref.upgrade() {
447 let mut parent_borrow = parent_strong.borrow_mut();
448 parent_borrow.first_child = Some(new_sibling.0);
449 }
450 }
451 }
452 }
453
454 pub fn from_html(html: Html) -> Option<Self> {
455 match html {
456 Html::Comment { .. } => None,
457 Html::Text { text } => Some(DomNode::create_text(text)),
458 Html::Element {
459 tag,
460 attributes,
461 children,
462 } => {
463 let node = DomNode::create_element_with_attributes(tag, attributes);
464 for c in children {
465 if let Some(n) = DomNode::from_html(c) {
466 node.append_child(n);
467 }
468 }
469 Some(node)
470 }
471 }
472 }
473}
474
475fn escape_html(text: &str) -> String {
477 text.chars()
478 .map(|c| match c {
479 '&' => "&".to_string(),
480 '<' => "<".to_string(),
481 '>' => ">".to_string(),
482 '"' => """.to_string(),
483 '\'' => "'".to_string(),
484 _ => c.to_string(),
485 })
486 .collect()
487}
488impl std::fmt::Display for DomNode {
489 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
490 match &*self.kind() {
491 DomNodeKind::Text { text } => write!(f, "{}", escape_html(text)),
492 DomNodeKind::Element { tag, attributes } => {
493 let attributes = attributes
494 .iter()
495 .map(|(k, v)| {
496 if !v.is_empty() {
497 format!(r#"{k}="{v}""#)
498 } else {
499 k.into()
500 }
501 })
502 .collect::<Vec<String>>()
503 .join(" ");
504
505 let spacing = if !attributes.is_empty() {
506 String::from(" ")
507 } else {
508 String::new()
509 };
510
511 let children: Vec<DomNode> = self.children().collect();
512 if children.is_empty() && is_void_element(tag) {
513 return write!(f, "<{tag}{spacing}{}/>", attributes);
514 }
515
516 let mut content = String::new();
517
518 for c in children {
519 content += &format!("{}", c);
520 }
521
522 write!(f, "<{tag}{spacing}{}>{}</{tag}>", attributes, content)
523 }
524 }
525 }
526}
527
528impl Clone for WeakDomNode {
530 fn clone(&self) -> Self {
531 WeakDomNode(Weak::clone(&self.0))
532 }
533}
534
535impl fmt::Debug for WeakDomNode {
536 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
537 f.write_str("(WeakNode)")
538 }
539}
540
541impl WeakDomNode {
542 pub fn upgrade(&self) -> Option<DomNode> {
544 self.0.upgrade().map(DomNode)
545 }
546}
547
548impl DomNodeData {
549 fn detach(&mut self) {
551 let parent_weak = self.parent.take();
552 let previous_sibling_weak = self.previous_sibling.take();
553 let next_sibling_strong = self.next_sibling.take();
554
555 let previous_sibling_opt = previous_sibling_weak
556 .as_ref()
557 .and_then(|weak| weak.upgrade());
558
559 if let Some(next_sibling_ref) = next_sibling_strong.as_ref() {
560 let mut next_sibling_borrow = next_sibling_ref.borrow_mut();
561 next_sibling_borrow.previous_sibling = previous_sibling_weak;
562 } else if let Some(parent_ref) = parent_weak.as_ref() {
563 if let Some(parent_strong) = parent_ref.upgrade() {
564 let mut parent_borrow = parent_strong.borrow_mut();
565 parent_borrow.last_child = previous_sibling_weak;
566 }
567 }
568
569 if let Some(previous_sibling_strong) = previous_sibling_opt {
570 let mut previous_sibling_borrow = previous_sibling_strong.borrow_mut();
571 previous_sibling_borrow.next_sibling = next_sibling_strong;
572 } else if let Some(parent_ref) = parent_weak.as_ref() {
573 if let Some(parent_strong) = parent_ref.upgrade() {
574 let mut parent_borrow = parent_strong.borrow_mut();
575 parent_borrow.first_child = next_sibling_strong;
576 }
577 }
578 }
579}
580
581impl Drop for DomNodeData {
582 fn drop(&mut self) {
583 let mut stack = Vec::new();
586 if let Some(first_child) = self.first_child.as_ref() {
587 let first_child = DomNode(first_child.clone());
589 for child1 in first_child.following_siblings() {
591 for child2 in child1.descendants() {
592 stack.push(child2);
593 }
594 }
595 }
596
597 for node in stack {
598 node.detach();
599 }
600 }
601}
602
603macro_rules! impl_node_iterator {
604 ($name: ident, $next: expr) => {
605 impl Iterator for $name {
606 type Item = DomNode;
607
608 fn next(&mut self) -> Option<Self::Item> {
612 match self.0.take() {
613 Some(node) => {
614 self.0 = $next(&node);
615 Some(node)
616 }
617 None => None,
618 }
619 }
620 }
621 };
622}
623
624pub struct Ancestors(Option<DomNode>);
626impl_node_iterator!(Ancestors, |node: &DomNode| node.parent());
627
628pub struct PrecedingSiblings(Option<DomNode>);
630impl_node_iterator!(PrecedingSiblings, |node: &DomNode| node.previous_sibling());
631
632pub struct FollowingSiblings(Option<DomNode>);
634impl_node_iterator!(FollowingSiblings, |node: &DomNode| node.next_sibling());
635
636pub struct Children {
638 next: Option<DomNode>,
639 next_back: Option<DomNode>,
640}
641
642impl Children {
643 fn finished(&self) -> bool {
645 match self.next_back {
646 Some(ref next_back) => next_back.next_sibling() == self.next,
647 _ => true,
648 }
649 }
650}
651
652impl Iterator for Children {
653 type Item = DomNode;
654
655 fn next(&mut self) -> Option<Self::Item> {
659 if self.finished() {
660 return None;
661 }
662
663 match self.next.take() {
664 Some(node) => {
665 self.next = node.next_sibling();
666 Some(node)
667 }
668 None => None,
669 }
670 }
671}
672
673impl DoubleEndedIterator for Children {
674 fn next_back(&mut self) -> Option<Self::Item> {
678 if self.finished() {
679 return None;
680 }
681
682 match self.next_back.take() {
683 Some(node) => {
684 self.next_back = node.previous_sibling();
685 Some(node)
686 }
687 None => None,
688 }
689 }
690}
691
692pub struct Descendants(Traverse);
694
695impl Iterator for Descendants {
696 type Item = DomNode;
697
698 fn next(&mut self) -> Option<Self::Item> {
702 loop {
703 match self.0.next() {
704 Some(NodeEdge::Start(node)) => return Some(node),
705 Some(NodeEdge::End(_)) => {}
706 None => return None,
707 }
708 }
709 }
710}
711
712#[derive(Clone, Debug)]
714pub enum NodeEdge {
715 Start(DomNode),
719
720 End(DomNode),
724}
725
726impl PartialEq for NodeEdge {
728 fn eq(&self, other: &NodeEdge) -> bool {
729 match (self, other) {
730 (NodeEdge::Start(n1), NodeEdge::Start(n2)) => *n1 == *n2,
731 (NodeEdge::End(n1), NodeEdge::End(n2)) => *n1 == *n2,
732 _ => false,
733 }
734 }
735}
736
737impl NodeEdge {
738 fn next_item(&self, root: &DomNode) -> Option<NodeEdge> {
739 match *self {
740 NodeEdge::Start(ref node) => match node.first_child() {
741 Some(first_child) => Some(NodeEdge::Start(first_child)),
742 None => Some(NodeEdge::End(node.clone())),
743 },
744 NodeEdge::End(ref node) => {
745 if *node == *root {
746 None
747 } else {
748 match node.next_sibling() {
749 Some(next_sibling) => Some(NodeEdge::Start(next_sibling)),
750 None => node.parent().map(NodeEdge::End),
755 }
756 }
757 }
758 }
759 }
760
761 fn previous_item(&self, root: &DomNode) -> Option<NodeEdge> {
762 match *self {
763 NodeEdge::End(ref node) => match node.last_child() {
764 Some(last_child) => Some(NodeEdge::End(last_child)),
765 None => Some(NodeEdge::Start(node.clone())),
766 },
767 NodeEdge::Start(ref node) => {
768 if *node == *root {
769 None
770 } else {
771 match node.previous_sibling() {
772 Some(previous_sibling) => Some(NodeEdge::End(previous_sibling)),
773 None => node.parent().map(NodeEdge::Start),
778 }
779 }
780 }
781 }
782 }
783}
784
785pub struct Traverse {
788 root: DomNode,
789 next: Option<NodeEdge>,
790 next_back: Option<NodeEdge>,
791}
792
793impl Traverse {
794 fn finished(&self) -> bool {
796 match self.next_back {
797 Some(ref next_back) => next_back.next_item(&self.root) == self.next,
798 _ => true,
799 }
800 }
801}
802
803impl Iterator for Traverse {
804 type Item = NodeEdge;
805
806 fn next(&mut self) -> Option<Self::Item> {
810 if self.finished() {
811 return None;
812 }
813
814 match self.next.take() {
815 Some(item) => {
816 self.next = item.next_item(&self.root);
817 Some(item)
818 }
819 None => None,
820 }
821 }
822}
823
824impl DoubleEndedIterator for Traverse {
825 fn next_back(&mut self) -> Option<Self::Item> {
829 if self.finished() {
830 return None;
831 }
832
833 match self.next_back.take() {
834 Some(item) => {
835 self.next_back = item.previous_item(&self.root);
836 Some(item)
837 }
838 None => None,
839 }
840 }
841}