From 595967d3722dba7f650c3ca7868837e6d2740213 Mon Sep 17 00:00:00 2001 From: Josh Date: Sat, 4 Jan 2025 17:38:20 -0600 Subject: [PATCH] combine tag open methods --- crates/djls-template-ast/src/parser.rs | 157 ++++++------------ ...er__tests__full_templates__parse_full.snap | 1 - ...st__parser__tests__style__parse_style.snap | 1 - 3 files changed, 52 insertions(+), 107 deletions(-) diff --git a/crates/djls-template-ast/src/parser.rs b/crates/djls-template-ast/src/parser.rs index 6d9d9ce..0b9098c 100644 --- a/crates/djls-template-ast/src/parser.rs +++ b/crates/djls-template-ast/src/parser.rs @@ -274,20 +274,33 @@ impl Parser { Ok(Node::Django(DjangoNode::Variable { bits, filters })) } - fn parse_html_tag_open(&mut self, s: &str) -> Result { + fn parse_tag_open(&mut self, s: &str, token_type: &TokenType) -> Result { let mut parts = s.split_whitespace(); - let tag_name = parts - .next() - .ok_or(ParserError::Ast(AstError::EmptyTag))? - .to_string(); - - if tag_name.to_lowercase() == "!doctype" { - return Ok(Node::Html(HtmlNode::Doctype("!DOCTYPE html".to_string()))); - } + // Only HTML needs the tag name from the input + let tag_name = match token_type { + TokenType::HtmlTagOpen(_) => { + let name = parts + .next() + .ok_or(ParserError::Ast(AstError::EmptyTag))? + .to_string(); + if name.to_lowercase() == "!doctype" { + return Ok(Node::Html(HtmlNode::Doctype("!DOCTYPE html".to_string()))); + } + name + } + TokenType::ScriptTagOpen(_) => { + parts.next(); // Skip the tag name + "script".to_string() + } + TokenType::StyleTagOpen(_) => { + parts.next(); // Skip the tag name + "style".to_string() + } + _ => return Err(ParserError::invalid_tag("Unknown tag type".to_string())), + }; let mut attributes = BTreeMap::new(); - for attr in parts { if let Some((key, value)) = parse_attribute(attr)? { attributes.insert(key, value); @@ -314,16 +327,37 @@ impl Parser { } if !found_closing_tag { - return Err(ParserError::Ast(AstError::UnclosedTag( - tag_name.to_string(), - ))); + return Err(ParserError::Ast(AstError::UnclosedTag(tag_name.clone()))); } - Ok(Node::Html(HtmlNode::Element { - tag_name, - attributes, - children, - })) + Ok(match token_type { + TokenType::HtmlTagOpen(_) => Node::Html(HtmlNode::Element { + tag_name, + attributes, + children, + }), + TokenType::ScriptTagOpen(_) => Node::Script(ScriptNode::Element { + attributes, + children, + }), + TokenType::StyleTagOpen(_) => Node::Style(StyleNode::Element { + attributes, + children, + }), + _ => return Err(ParserError::invalid_tag("Unknown tag type".to_string())), + }) + } + + fn parse_html_tag_open(&mut self, s: &str) -> Result { + self.parse_tag_open(s, &TokenType::HtmlTagOpen(String::new())) + } + + fn parse_script_tag_open(&mut self, s: &str) -> Result { + self.parse_tag_open(s, &TokenType::ScriptTagOpen(String::new())) + } + + fn parse_style_tag_open(&mut self, s: &str) -> Result { + self.parse_tag_open(s, &TokenType::StyleTagOpen(String::new())) } fn parse_html_tag_void(&mut self, s: &str) -> Result { @@ -348,93 +382,6 @@ impl Parser { })) } - fn parse_script_tag_open(&mut self, s: &str) -> Result { - let mut parts = s.split_whitespace(); - - let _tag_name = parts - .next() - .ok_or(ParserError::Ast(AstError::EmptyTag))? - .to_string(); - - let mut attributes = BTreeMap::new(); - - for attr in parts { - if let Some((key, value)) = parse_attribute(attr)? { - attributes.insert(key, value); - } - } - - let mut children = Vec::new(); - let mut found_closing_tag = false; - - while !self.is_at_end() { - match self.next_node() { - Ok(node) => { - children.push(node); - } - Err(ParserError::ErrorSignal(Signal::ClosingTagFound(tag))) => { - if tag == "script" { - found_closing_tag = true; - self.consume()?; - break; - } - } - Err(e) => return Err(e), - } - } - - if !found_closing_tag { - return Err(ParserError::Ast(AstError::UnclosedTag( - "script".to_string(), - ))); - } - - Ok(Node::Script(ScriptNode::Element { - attributes, - children, - })) - } - - fn parse_style_tag_open(&mut self, s: &str) -> Result { - let parts = s.split_whitespace(); - - let mut attributes = BTreeMap::new(); - - for attr in parts { - if let Some((key, value)) = parse_attribute(attr)? { - attributes.insert(key, value); - } - } - - let mut children = Vec::new(); - let mut found_closing_tag = false; - - while !self.is_at_end() { - match self.next_node() { - Ok(node) => { - children.push(node); - } - Err(ParserError::ErrorSignal(Signal::ClosingTagFound(tag))) => { - if tag == "style" { - found_closing_tag = true; - self.consume()?; - break; - } - } - Err(e) => return Err(e), - } - } - - if !found_closing_tag { - return Err(ParserError::Ast(AstError::UnclosedTag("style".to_string()))); - } - - Ok(Node::Style(StyleNode::Element { - attributes, - children, - })) - } - fn peek(&self) -> Result { self.peek_at(0) } diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__full_templates__parse_full.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__full_templates__parse_full.snap index c234ccf..7bada8e 100644 --- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__full_templates__parse_full.snap +++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__full_templates__parse_full.snap @@ -18,7 +18,6 @@ nodes: - Style: Element: attributes: - style: Boolean type: Value: text/css children: diff --git a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__style__parse_style.snap b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__style__parse_style.snap index d31e4f9..5f8c0a9 100644 --- a/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__style__parse_style.snap +++ b/crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__style__parse_style.snap @@ -6,7 +6,6 @@ nodes: - Style: Element: attributes: - style: Boolean type: Value: text/css children: