node_html_parser/dom/element/
serialize.rs1use super::main::HTMLElement; use super::normalize_attr_quotes; impl HTMLElement {
5 pub fn outer_html(&self) -> String {
6 if self.is_root() {
7 return self.inner_html();
8 } let tag = self.name();
10 let attrs = if self.raw_attrs.is_empty() {
11 String::new()
12 } else {
13 format!(" {}", self.raw_attrs.trim())
14 };
15 let should_normalize = self.attrs_modified;
16 if self.is_void {
17 if self.void_add_slash {
18 let mut norm_attrs = if attrs.is_empty() {
24 String::new()
25 } else if should_normalize {
26 normalize_attr_quotes(&attrs, true)
27 } else {
28 normalize_attr_quotes(&attrs, false)
29 };
30 if !norm_attrs.is_empty() {
32 let mut converted = String::with_capacity(norm_attrs.len());
33 let nb = norm_attrs.as_bytes();
34 let mut i = 0;
35 while i < nb.len() {
36 let c = nb[i] as char;
37 if c == '\'' {
38 converted.push(c);
40 i += 1;
41 continue;
42 }
43 if c == '=' && i + 1 < nb.len() && nb[i + 1] as char == '\'' {
45 converted.push('=');
46 converted.push('"');
47 i += 2; let start = i;
49 while i < nb.len() && nb[i] as char != '\'' {
50 i += 1;
51 }
52 let val = &norm_attrs[start..i];
53 if val.contains('"') {
55 converted.push('\'');
56 converted.push_str(val);
57 converted.push('\'');
58 } else {
59 converted.push_str(val);
60 converted.push('"');
61 }
62 if i < nb.len() && nb[i] as char == '\'' {
63 i += 1;
64 }
65 continue;
66 }
67 converted.push(c);
68 i += 1;
69 }
70 norm_attrs = converted;
71 }
72 if norm_attrs.is_empty() {
73 format!("<{}{}{}>", tag, norm_attrs, "/")
74 } else if norm_attrs.ends_with(' ') {
75 format!("<{}{}{}>", tag, norm_attrs, "/")
76 } else {
77 format!("<{}{} {}>", tag, norm_attrs, "/")
78 }
79 } else {
80 let norm_attrs = if attrs.is_empty() {
81 String::new()
82 } else if should_normalize {
83 normalize_attr_quotes(&attrs, true)
84 } else {
85 normalize_attr_quotes(&attrs, false)
86 };
87 format!("<{}{}>", tag, norm_attrs)
88 }
89 } else {
90 let norm_attrs = if attrs.is_empty() {
92 String::new()
93 } else if should_normalize {
94 normalize_attr_quotes(&attrs, true)
95 } else {
96 normalize_attr_quotes(&attrs, false)
97 };
98 let auto_closed_empty = match self.range() {
101 Some((s, e)) if s == e && self.children.is_empty() => true,
102 _ => false,
103 };
104 if auto_closed_empty {
105 format!("<{}{}>", tag, norm_attrs)
106 } else {
107 format!("<{}{}>{}</{}>", tag, norm_attrs, self.inner_html(), tag)
108 }
109 }
110 }
111 pub fn to_string(&self) -> String {
113 self.outer_html()
114 }
115}