1pub fn inject_bridge_script(html: &str, bridge_url: &str) -> String {
25 let script_tag = format!(r#"<script type="module" src="{}"></script>"#, bridge_url);
26
27 if let Some(pos) = html.find("</head>") {
28 let mut result = String::with_capacity(html.len() + script_tag.len() + 1);
30 result.push_str(&html[..pos]);
31 result.push_str(&script_tag);
32 result.push('\n');
33 result.push_str(&html[pos..]);
34 result
35 } else if let Some(pos) = html.find("<body") {
36 if let Some(close) = html[pos..].find('>') {
38 let insert_at = pos + close + 1;
39 let mut result = String::with_capacity(html.len() + script_tag.len() + 1);
40 result.push_str(&html[..insert_at]);
41 result.push('\n');
42 result.push_str(&script_tag);
43 result.push_str(&html[insert_at..]);
44 result
45 } else {
46 format!("{}\n{}", script_tag, html)
47 }
48 } else {
49 format!("{}\n{}", script_tag, html)
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 #[test]
59 fn injects_before_head_close() {
60 let html = "<html><head><title>T</title></head><body></body></html>";
61 let result = inject_bridge_script(html, "/bridge.mjs");
62 assert!(result.contains(r#"<script type="module" src="/bridge.mjs"></script>"#));
63 assert!(result.find("bridge.mjs").unwrap() < result.find("</head>").unwrap());
64 }
65
66 #[test]
67 fn injects_after_body_open_when_no_head() {
68 let html = "<body><div>Content</div></body>";
69 let result = inject_bridge_script(html, "/bridge.mjs");
70 assert!(result.contains(r#"<script type="module" src="/bridge.mjs"></script>"#));
71 assert!(result.find("bridge.mjs").unwrap() > result.find("<body>").unwrap());
72 }
73
74 #[test]
75 fn prepends_when_no_head_or_body() {
76 let html = "<div>Simple widget</div>";
77 let result = inject_bridge_script(html, "/bridge.mjs");
78 assert!(result.starts_with(r#"<script type="module" src="/bridge.mjs"></script>"#));
79 }
80}