Skip to content

Commit c7fb8c3

Browse files
committed
to html
1 parent d45ecc1 commit c7fb8c3

3 files changed

Lines changed: 96 additions & 1 deletion

File tree

src/dom/element.rs

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::node::Node;
1+
use super::node::{Node, write_html_list};
22
#[cfg(feature = "source-span")]
33
use super::span::SourceSpan;
44
use crate::dom::vecmap::VecMap;
@@ -92,6 +92,60 @@ impl<'a> Element<'a> {
9292
{
9393
let _ = for_each_element_async(self.children.as_mut_slice(), &mut f).await;
9494
}
95+
96+
#[inline(always)]
97+
pub fn to_html(&self) -> String {
98+
let mut result = String::new();
99+
self.write_html(&mut result);
100+
result
101+
}
102+
103+
pub fn write_html(&self, writer: &mut String) {
104+
let e = self;
105+
106+
writer.push('<');
107+
writer.push_str(&e.name);
108+
if !e.classes.is_empty() {
109+
writer.push_str(" class=\"");
110+
writer.push_str(
111+
&e.classes
112+
.iter()
113+
.map(|c| c.as_str())
114+
.collect::<Vec<_>>()
115+
.join(" "),
116+
);
117+
writer.push('"');
118+
}
119+
if let Some(id) = &e.id {
120+
writer.push(' ');
121+
writer.push_str("id");
122+
writer.push('=');
123+
writer.push('"');
124+
writer.push_str(id);
125+
writer.push('"');
126+
}
127+
for (k, v) in e.attributes.iter() {
128+
writer.push(' ');
129+
writer.push_str(k);
130+
if let Some(v) = v {
131+
writer.push('=');
132+
writer.push('"');
133+
writer.push_str(v);
134+
writer.push('"');
135+
}
136+
}
137+
if e.variant == ElementVariant::Normal {
138+
writer.push('>');
139+
write_html_list(writer, &e.children);
140+
writer.push('<');
141+
writer.push('/');
142+
writer.push_str(&e.name);
143+
writer.push('>');
144+
} else {
145+
writer.push('/');
146+
writer.push('>');
147+
}
148+
}
95149
}
96150

97151
pub(crate) fn for_each_element<'a, F>(tree: &mut [Node<'a>], f: &mut F) -> ControlFlow<(), ()>

src/dom/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub mod vecmap;
1919
pub mod vecset;
2020

2121
use crate::dom::element::{WalkResult, for_each_element, for_each_element_async};
22+
use crate::dom::node::write_html_list;
2223
#[cfg(feature = "source-span")]
2324
use crate::dom::span::SourceSpan;
2425
use element::{Element, ElementVariant};
@@ -385,4 +386,16 @@ impl<'a> Dom<'a> {
385386
{
386387
let _ = for_each_element_async(self.children.as_mut_slice(), &mut f).await;
387388
}
389+
390+
#[inline(always)]
391+
pub fn to_html(&self) -> String {
392+
let mut result = String::new();
393+
self.write_html(&mut result);
394+
result
395+
}
396+
397+
#[inline(always)]
398+
pub fn write_html(&self, writer: &mut String) {
399+
write_html_list(writer, self.children.as_slice());
400+
}
388401
}

src/dom/node.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,34 @@ impl<'a> Node<'a> {
6767
let _ = for_each_element_async(e.children.as_mut_slice(), &mut f).await;
6868
}
6969
}
70+
71+
#[inline]
72+
pub fn to_html(&self) -> String {
73+
let mut result = String::new();
74+
self.write_html(&mut result);
75+
result
76+
}
77+
78+
#[inline]
79+
pub fn write_html(&self, writer: &mut String) {
80+
match self {
81+
Node::Text(s) => {
82+
writer.push_str(s);
83+
}
84+
Node::Element(e) => e.write_html(writer),
85+
Node::Comment(c) => {
86+
writer.push_str("<!--");
87+
writer.push_str(c);
88+
writer.push_str("-->");
89+
}
90+
}
91+
}
92+
}
93+
94+
pub(crate) fn write_html_list(writer: &mut String, list: &[Node]) {
95+
for n in list {
96+
n.write_html(writer);
97+
}
7098
}
7199

72100
impl<'a> IntoIterator for &'a Node<'a> {

0 commit comments

Comments
 (0)