use std::ops::Deref;
use html5ever::{tendril::StrTendril, Attribute, LocalName, QualName};
use indexmap::IndexSet;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Node {
Document,
Fragment,
Doctype(Doctype),
Comment(Comment),
Text(Text),
Element(Element),
ProcessingInstruction(ProcessingInstruction),
}
impl Node {
pub fn as_element(&self) -> Option<&Element> {
match *self {
Node::Element(ref e) => Some(e),
_ => None,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Doctype {
pub name: StrTendril,
pub public_id: StrTendril,
pub system_id: StrTendril,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Comment {
pub comment: StrTendril,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Text {
pub text: StrTendril,
}
pub type Attributes = indexmap::IndexMap<QualName, StrTendril>;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Element {
pub name: QualName,
pub id: Option<LocalName>,
pub classes: IndexSet<LocalName>,
pub attrs: Attributes,
}
impl Element {
#[doc(hidden)]
pub fn new(name: QualName, attrs: Vec<Attribute>) -> Self {
let id = attrs
.iter()
.find(|a| a.name.local.deref() == "id")
.map(|a| LocalName::from(a.value.deref()));
let classes: IndexSet<LocalName> = attrs
.iter()
.find(|a| a.name.local.deref() == "class")
.map_or(IndexSet::new(), |a| {
a.value
.deref()
.split_whitespace()
.map(LocalName::from)
.collect()
});
Element {
attrs: attrs.into_iter().map(|a| (a.name, a.value)).collect(),
name,
id,
classes,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ProcessingInstruction {
pub target: StrTendril,
pub data: StrTendril,
}