use rdom_core::{Dom, NodeId, NodeType};
use rdom_parser::parse;
fn main() {
let template = r#"
<div class="card" id="hero">
<h1>Welcome & hello</h1>
<p>This is <strong>rdom-parser</strong>.</p>
<!-- TODO: add icon -->
<ul>
<li>Zero external deps</li>
<li>Full UTF-8: δΈζ, π¦, π¨βπ©βπ§</li>
<li>Error reporting with line/col + hints</li>
</ul>
<button disabled>OK</button>
</div>
"#;
let (dom, _ids): (Dom<()>, _) = parse(template).unwrap();
let root = dom.root();
println!("ββ Parsed tree βββββββββββββββββββββββββββββββββ");
walk(&dom, root, 0);
println!("\nββ Selector queries ββββββββββββββββββββββββββββ");
let lis = dom.query_selector_all_in(root, "li").unwrap();
println!("Found {} <li>:", lis.len());
for li in lis {
println!(" β’ {}", dom.text_content(li));
}
let card = dom.query_selector_in(root, ".card").unwrap().unwrap();
println!(
"\n.card's id attribute: {:?}",
dom.get_attribute(card, "id")
);
let button = dom.query_selector_in(root, "button[disabled]").unwrap();
if let Some(b) = button {
println!("Disabled button: {}", dom.text_content(b));
}
println!("\nββ Text content (flattened) ββββββββββββββββββββ");
println!(
"{}",
dom.text_content(card)
.split_whitespace()
.collect::<Vec<_>>()
.join(" ")
);
}
fn walk(dom: &Dom<()>, id: NodeId, depth: usize) {
let indent = " ".repeat(depth);
let node = dom.node(id);
match node.node_type() {
NodeType::Element => {
let tag = node.tag_name().unwrap_or("?");
let attrs: Vec<String> = dom
.attributes(id)
.map(|(k, v)| format!(r#" {k}="{v}""#))
.collect();
let classes: Vec<&str> = dom.class_list(id).collect();
let class_attr = if classes.is_empty() {
String::new()
} else {
format!(r#" class="{}""#, classes.join(" "))
};
println!("{indent}<{tag}{class_attr}{}>", attrs.join(""));
for child in node.child_nodes() {
walk(dom, child.id(), depth + 1);
}
if node.has_child_nodes() {
println!("{indent}</{tag}>");
}
}
NodeType::Text => {
let s = node.node_value().unwrap_or("").trim();
if !s.is_empty() {
println!("{indent}{s:?}");
}
}
NodeType::Comment => {
println!("{indent}<!--{}-->", node.node_value().unwrap_or(""));
}
NodeType::Fragment => {
for child in node.child_nodes() {
walk(dom, child.id(), depth);
}
}
other => println!("{indent}<!-- {other:?} -->"),
}
}