1pub const NS_HTML: &str = "http://www.w3.org/1999/xhtml";
3pub const NS_DEFAULT: &str = "";
5
6pub type LocalName = string_cache::Atom<super::LocalNameStaticSet>;
8pub type Prefix = string_cache::Atom<super::PrefixStaticSet>;
10pub type Namespace = string_cache::Atom<super::NamespaceStaticSet>;
12pub type Handle = usize;
14
15pub fn namespace_equals_or_html(ns1: &str, ns2: &str) -> bool {
18 match (ns1, ns2) {
19 (NS_DEFAULT, NS_HTML) | (NS_HTML, NS_DEFAULT) => true,
20 (want, have) => want == have,
21 }
22}
23
24#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)]
29pub enum QuirksMode {
30 Quirks,
32 LimitedQuirks,
34 NoQuirks,
36}
37
38#[derive(Default, Debug, Clone)]
40pub struct Element {
41 pub name: LocalName,
42 pub namespace: Namespace,
43 pub prefix: Option<Prefix>,
44 pub attrs: Vec<Attribute>,
45 pub kind: ElementKind,
46}
47#[derive(Default, Debug, Clone)]
49pub struct Attribute {
50 pub name: LocalName,
51 pub namespace: Namespace,
52 pub prefix: Option<Prefix>,
53 pub value: super::StrTendril,
54}
55
56#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
58pub enum ElementKind {
59 #[default]
61 Regular,
62 Template,
64 MathmlPoint,
66}
67
68#[derive(Debug, Clone)]
70pub enum Content {
71 Document,
72 Element(Element),
73 Comment {
74 text: String,
75 },
76 ProcessingInstruction {
77 target: String,
78 data: String,
79 },
80 Text {
81 text: String,
82 },
83 DocType {
84 name: String,
85 public_id: String,
86 system_id: String,
87 },
88}
89impl Content {
90 pub fn element_name(&self) -> Option<(&str, &str)> {
92 match self {
93 Content::Document
95 | Content::Element(Element {
96 kind: ElementKind::Template,
97 ..
98 })
99 | Content::Comment { .. }
100 | Content::ProcessingInstruction { .. }
101 | Content::Text { .. }
102 | Content::DocType { .. } => None,
103 Content::Element(Element {
105 name, namespace, ..
106 }) => Some((name, namespace)),
107 }
108 }
109 pub(crate) fn attributes(&self) -> impl DoubleEndedIterator<Item = &Attribute> {
111 match self {
112 Content::Document
114 | Content::Element(Element {
115 kind: ElementKind::Template,
116 ..
117 })
118 | Content::Comment { .. }
119 | Content::ProcessingInstruction { .. }
120 | Content::Text { .. }
121 | Content::DocType { .. } => [].iter(),
122 Content::Element(Element { attrs, .. }) => attrs.iter(),
124 }
125 }
126 pub fn is_template(&self) -> bool {
128 matches!(
129 self,
130 Content::Element(Element {
131 kind: ElementKind::Template,
132 ..
133 })
134 )
135 }
136}
137impl Default for Content {
138 fn default() -> Self {
139 Self::Document
140 }
141}
142impl std::fmt::Display for Content {
143 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
144 match self {
145 Content::Document => f.write_str("document"),
146 Content::Element(Element { name, attrs, .. }) => {
147 f.write_fmt(format_args!("{}", name))?;
148 for attr in attrs {
149 f.write_fmt(format_args!(" {}={:?}", attr.name, attr.value.to_string()))?;
150 }
151 Ok(())
152 }
153 Content::Comment { text } => f.write_fmt(format_args!("<!-- {text:?} -->")),
154 Content::ProcessingInstruction { target, data } => {
155 f.write_fmt(format_args!("<?{target} {data} ?>"))
156 }
157 Content::Text { text } => f.write_fmt(format_args!("{text:?}")),
158 Content::DocType {
159 name,
160 public_id,
161 system_id,
162 } => f.write_fmt(format_args!("<!DOCTYPE {name} {public_id} {system_id}>")),
163 }
164 }
165}