muffy_document/html/
document.rs1use super::{element::Element, node::Node};
2use alloc::sync::Arc;
3use core::ops::Deref;
4use markup5ever_rcdom::NodeData;
5
6#[derive(Debug, Eq, PartialEq)]
8pub struct Document {
9 children: Vec<Arc<Node>>,
10}
11
12impl Document {
13 pub const fn new(children: Vec<Arc<Node>>) -> Self {
15 Self { children }
16 }
17
18 pub fn children(&self) -> impl Iterator<Item = &Node> {
20 self.children.iter().map(Deref::deref)
21 }
22
23 pub fn base(&self) -> Option<&str> {
25 self.children()
26 .find_map(|node| Self::find_base(node))
27 .and_then(|element| {
28 element
29 .attributes()
30 .find(|(key, _)| *key == "href")
31 .map(|(_, value)| value)
32 })
33 }
34
35 fn find_base(node: &Node) -> Option<&Element> {
36 match node {
37 Node::Element(element) if element.name() == "base" => Some(element),
38 Node::Element(element) => element.children().find_map(|node| Self::find_base(node)),
39 _ => None,
40 }
41 }
42
43 pub(crate) fn from_markup5ever(node: &markup5ever_rcdom::Node) -> Self {
44 if matches!(node.data, NodeData::Document) {
45 Self::new(
46 node.children
47 .borrow()
48 .iter()
49 .flat_map(|node| Node::from_markup5ever(node))
50 .map(Arc::new)
51 .collect(),
52 )
53 } else {
54 unreachable!()
55 }
56 }
57}