pub const NS_HTML: &str = "http://www.w3.org/1999/xhtml";
pub const NS_DEFAULT: &str = "";
pub type LocalName = string_cache::Atom<super::LocalNameStaticSet>;
pub type Prefix = string_cache::Atom<super::PrefixStaticSet>;
pub type Namespace = string_cache::Atom<super::NamespaceStaticSet>;
pub type Handle = usize;
pub fn namespace_equals_or_html(ns1: &str, ns2: &str) -> bool {
match (ns1, ns2) {
(NS_DEFAULT, NS_HTML) | (NS_HTML, NS_DEFAULT) => true,
(want, have) => want == have,
}
}
#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)]
pub enum QuirksMode {
Quirks,
LimitedQuirks,
NoQuirks,
}
#[derive(Default, Debug, Clone)]
pub struct Element {
pub name: LocalName,
pub namespace: Namespace,
pub prefix: Option<Prefix>,
pub attrs: Vec<Attribute>,
pub kind: ElementKind,
}
#[derive(Default, Debug, Clone)]
pub struct Attribute {
pub name: LocalName,
pub namespace: Namespace,
pub prefix: Option<Prefix>,
pub value: super::StrTendril,
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
pub enum ElementKind {
#[default]
Regular,
Template,
MathmlPoint,
}
#[derive(Debug, Clone)]
pub enum Content {
Document,
Element(Element),
Comment {
text: String,
},
ProcessingInstruction {
target: String,
data: String,
},
Text {
text: String,
},
DocType {
name: String,
public_id: String,
system_id: String,
},
}
impl Content {
pub fn element_name(&self) -> Option<(&str, &str)> {
match self {
Content::Document
| Content::Element(Element {
kind: ElementKind::Template,
..
})
| Content::Comment { .. }
| Content::ProcessingInstruction { .. }
| Content::Text { .. }
| Content::DocType { .. } => None,
Content::Element(Element {
name, namespace, ..
}) => Some((name, namespace)),
}
}
pub(crate) fn attributes(&self) -> impl DoubleEndedIterator<Item = &Attribute> {
match self {
Content::Document
| Content::Element(Element {
kind: ElementKind::Template,
..
})
| Content::Comment { .. }
| Content::ProcessingInstruction { .. }
| Content::Text { .. }
| Content::DocType { .. } => [].iter(),
Content::Element(Element { attrs, .. }) => attrs.iter(),
}
}
pub fn is_template(&self) -> bool {
matches!(
self,
Content::Element(Element {
kind: ElementKind::Template,
..
})
)
}
}
impl Default for Content {
fn default() -> Self {
Self::Document
}
}
impl std::fmt::Display for Content {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Content::Document => f.write_str("document"),
Content::Element(Element { name, attrs, .. }) => {
f.write_fmt(format_args!("{}", name))?;
for attr in attrs {
f.write_fmt(format_args!(" {}={:?}", attr.name, attr.value.to_string()))?;
}
Ok(())
}
Content::Comment { text } => f.write_fmt(format_args!("<!-- {text:?} -->")),
Content::ProcessingInstruction { target, data } => {
f.write_fmt(format_args!("<?{target} {data} ?>"))
}
Content::Text { text } => f.write_fmt(format_args!("{text:?}")),
Content::DocType {
name,
public_id,
system_id,
} => f.write_fmt(format_args!("<!DOCTYPE {name} {public_id} {system_id}>")),
}
}
}