1use super::*;
2
3pub fn inner_text(element: &Element) -> String {
8 fn inner_text_(element: &Element, buf: &mut String) {
9 if let "math" | "svg" | "title" = element.tag_name.as_str() {
10 return;
11 }
12 if let ElementChildren::Children(ref children) = element.children {
13 for child in children {
14 match child {
15 Node::Element(element) => {
16 inner_text_(element, buf);
17 }
18 Node::TextNode(content) => {
19 buf.push_str(&unescape_string_content(content));
20 }
21 Node::Comment(..) => {}
22 }
23 }
24 }
25 }
26
27 let mut s = String::new();
28 inner_text_(element, &mut s);
29 s
30}
31
32#[must_use]
34pub fn unescape_string_content(on: &str) -> Cow<'_, str> {
35 let mut result = Cow::Borrowed("");
36 let mut start = 0;
37 for (index, _matched) in on.match_indices('&') {
38 result += &on[start..index];
39 let after = &on[(index + '&'.len_utf8())..];
40 if after.starts_with("quot;") {
41 start = index + "quot;".len();
42 result += "\"";
43 } else if after.starts_with("amp;") {
44 start = index + "amp;".len();
45 result += "&";
46 } else if after.starts_with("lt;") {
47 start = index + "lt;".len();
48 result += "<";
49 } else if after.starts_with("gt;") {
50 start = index + "gt;".len();
51 result += ">";
52 } else if let Some(after) = after.strip_prefix('#') {
53 let mut found = false;
54 for (idx, chr) in after.char_indices() {
55 if let ';' = chr {
56 let item = &after[..idx];
58 let code: u32 = if let Some(rest) = item.strip_prefix(['x', 'X']) {
59 let mut value = 0u32;
60 for c in rest.as_bytes() {
61 value <<= 4; match c {
63 b'0'..=b'9' => {
64 value += u32::from(c - b'0');
65 }
66 b'a'..=b'f' => {
67 value += u32::from(c - b'a') + 10;
68 }
69 b'A'..=b'F' => {
70 value += u32::from(c - b'A') + 10;
71 }
72 chr => panic!("{chr:?}"),
73 }
74 }
75 value
76 } else {
77 item.parse().unwrap()
78 };
79 let entity = char::from_u32(code).unwrap().to_string();
80 let mut out = result.into_owned();
82 out.push_str(&entity);
83 result = Cow::Owned(out);
84 start = index + "&#".len() + idx + ";".len();
85 found = true;
86 break;
87 }
88 }
89 if !found {
90 panic!()
91 }
92 }
93 }
94 result += &on[start..];
95 result
96}