diff --git a/Cargo.lock b/Cargo.lock index 685ce36..da04974 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,24 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "html-escape" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1ad449764d627e22bfd7cd5e8868264fc9236e07c752972b4080cd351cb476" +dependencies = [ + "utf8-width", +] + [[package]] name = "html_editor" version = "0.6.1" +dependencies = [ + "html-escape", +] + +[[package]] +name = "utf8-width" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1" diff --git a/Cargo.toml b/Cargo.toml index 6502e5d..2cf436f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,3 +10,4 @@ license = "MIT" keywords = ["html", "parser", "editor", "dom"] [dependencies] +html-escape = "0.2.13" diff --git a/src/lib.rs b/src/lib.rs index e8f2628..7d93575 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,6 +52,12 @@ pub enum Doctype { #[derive(Debug, Clone)] pub enum Node { Element(Element), + /// A text node in the DOM. The contents of the `Text` has all entities expanded. + /// For example parsing `I <3 HTML` would result in a `Text("I <3 HTML")`. + /// + /// Note that ` + + + "#; + + let html = parse(HTML).unwrap(); + + let script_selector = Selector::from("script"); + + let Some(script) = html.query(&script_selector) else { + assert!(false, "script selector failed to match"); + unreachable!() + }; + assert_eq!(script.name, "script"); + + match script.children.get(0) { + Some(Node::Text(script_content)) => assert_eq!(script_content, r#"let text = "this tag shouldn't be escaped ->

hi

""#), + _ => { + assert!(false, "script had no text children"); + return; + } + } + + let style_selector = Selector::from("style"); + + let Some(style) = html.query(&style_selector) else { + assert!(false, "Couldn't find style"); + return; + }; + + match style.children.get(0) { + Some(Node::Text(style_content)) => assert_eq!(style_content, r#"main:before { content: "fake tag"; }"#), + _ => { + assert!(false, "style had no text children"); + return; + } + } +} + +#[test] +fn no_escapes_in_script_and_style() { + let element = Element::new( + "head", + vec![], + vec![ + Node::Element(Element::new( + "script", + vec![], + vec![Node::Text(r#"let text = "this tag shouldn't be escaped ->

hi

""#.into())], + )), + Node::Element(Element::new( + "style", + vec![], + vec![Node::Text(r#"main:before { content: "fake tag"; }"#.into())], + )), + ], + ); + + let generated = element.html(); + assert_eq!(generated, r#""#); +}