1use crate::common::get_tag_attr;
2use crate::dummy::IdentityHandler;
3use crate::markup5ever_rcdom;
4use percent_encoding::percent_decode_str;
5
6use super::StructuredPrinter;
7use super::TagHandler;
8
9use markup5ever_rcdom::{Handle, NodeData};
10
11#[derive(Default)]
12pub struct AnchorHandler {
13 start_pos: usize,
14 url: String,
15 emit_unchanged: bool,
16}
17
18impl TagHandler for AnchorHandler {
19 fn handle(&mut self, tag: &Handle, printer: &mut StructuredPrinter) {
20 if get_tag_attr(tag, "name").is_some() {
23 let mut identity = IdentityHandler;
24 identity.handle(tag, printer);
25 self.emit_unchanged = true;
26 }
27
28 self.start_pos = printer.data.len();
29
30 self.url = match tag.data {
32 NodeData::Element { ref attrs, .. } => {
33 let attrs = attrs.borrow();
34 let href = attrs
35 .iter()
36 .find(|attr| attr.name.local.to_string() == "href");
37 match href {
38 Some(link) => {
39 let link = &*link.value;
40 let link = percent_decode_str(link).decode_utf8().unwrap_or_default();
41
42 if link.contains(|c: char| c.is_ascii_whitespace()) {
43 format!("<{}>", link)
44 } else {
45 link.to_string()
46 }
47 }
48 None => String::new(),
49 }
50 }
51 _ => String::new(),
52 };
53 }
54
55 fn after_handle(&mut self, printer: &mut StructuredPrinter) {
56 if !self.emit_unchanged {
57 printer.insert_str(self.start_pos, "[");
59 printer.append_str(&format!("]({})", self.url))
60 }
61 }
62}