Skip to content

Commit 595967d

Browse files
combine tag open methods
1 parent 50c451e commit 595967d

File tree

3 files changed

+53
-108
lines changed

3 files changed

+53
-108
lines changed

crates/djls-template-ast/src/parser.rs

Lines changed: 53 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -274,20 +274,33 @@ impl Parser {
274274
Ok(Node::Django(DjangoNode::Variable { bits, filters }))
275275
}
276276

277-
fn parse_html_tag_open(&mut self, s: &str) -> Result<Node, ParserError> {
277+
fn parse_tag_open(&mut self, s: &str, token_type: &TokenType) -> Result<Node, ParserError> {
278278
let mut parts = s.split_whitespace();
279279

280-
let tag_name = parts
281-
.next()
282-
.ok_or(ParserError::Ast(AstError::EmptyTag))?
283-
.to_string();
284-
285-
if tag_name.to_lowercase() == "!doctype" {
286-
return Ok(Node::Html(HtmlNode::Doctype("!DOCTYPE html".to_string())));
287-
}
280+
// Only HTML needs the tag name from the input
281+
let tag_name = match token_type {
282+
TokenType::HtmlTagOpen(_) => {
283+
let name = parts
284+
.next()
285+
.ok_or(ParserError::Ast(AstError::EmptyTag))?
286+
.to_string();
287+
if name.to_lowercase() == "!doctype" {
288+
return Ok(Node::Html(HtmlNode::Doctype("!DOCTYPE html".to_string())));
289+
}
290+
name
291+
}
292+
TokenType::ScriptTagOpen(_) => {
293+
parts.next(); // Skip the tag name
294+
"script".to_string()
295+
}
296+
TokenType::StyleTagOpen(_) => {
297+
parts.next(); // Skip the tag name
298+
"style".to_string()
299+
}
300+
_ => return Err(ParserError::invalid_tag("Unknown tag type".to_string())),
301+
};
288302

289303
let mut attributes = BTreeMap::new();
290-
291304
for attr in parts {
292305
if let Some((key, value)) = parse_attribute(attr)? {
293306
attributes.insert(key, value);
@@ -314,16 +327,37 @@ impl Parser {
314327
}
315328

316329
if !found_closing_tag {
317-
return Err(ParserError::Ast(AstError::UnclosedTag(
318-
tag_name.to_string(),
319-
)));
320-
}
330+
return Err(ParserError::Ast(AstError::UnclosedTag(tag_name.clone())));
331+
}
332+
333+
Ok(match token_type {
334+
TokenType::HtmlTagOpen(_) => Node::Html(HtmlNode::Element {
335+
tag_name,
336+
attributes,
337+
children,
338+
}),
339+
TokenType::ScriptTagOpen(_) => Node::Script(ScriptNode::Element {
340+
attributes,
341+
children,
342+
}),
343+
TokenType::StyleTagOpen(_) => Node::Style(StyleNode::Element {
344+
attributes,
345+
children,
346+
}),
347+
_ => return Err(ParserError::invalid_tag("Unknown tag type".to_string())),
348+
})
349+
}
321350

322-
Ok(Node::Html(HtmlNode::Element {
323-
tag_name,
324-
attributes,
325-
children,
326-
}))
351+
fn parse_html_tag_open(&mut self, s: &str) -> Result<Node, ParserError> {
352+
self.parse_tag_open(s, &TokenType::HtmlTagOpen(String::new()))
353+
}
354+
355+
fn parse_script_tag_open(&mut self, s: &str) -> Result<Node, ParserError> {
356+
self.parse_tag_open(s, &TokenType::ScriptTagOpen(String::new()))
357+
}
358+
359+
fn parse_style_tag_open(&mut self, s: &str) -> Result<Node, ParserError> {
360+
self.parse_tag_open(s, &TokenType::StyleTagOpen(String::new()))
327361
}
328362

329363
fn parse_html_tag_void(&mut self, s: &str) -> Result<Node, ParserError> {
@@ -348,93 +382,6 @@ impl Parser {
348382
}))
349383
}
350384

351-
fn parse_script_tag_open(&mut self, s: &str) -> Result<Node, ParserError> {
352-
let mut parts = s.split_whitespace();
353-
354-
let _tag_name = parts
355-
.next()
356-
.ok_or(ParserError::Ast(AstError::EmptyTag))?
357-
.to_string();
358-
359-
let mut attributes = BTreeMap::new();
360-
361-
for attr in parts {
362-
if let Some((key, value)) = parse_attribute(attr)? {
363-
attributes.insert(key, value);
364-
}
365-
}
366-
367-
let mut children = Vec::new();
368-
let mut found_closing_tag = false;
369-
370-
while !self.is_at_end() {
371-
match self.next_node() {
372-
Ok(node) => {
373-
children.push(node);
374-
}
375-
Err(ParserError::ErrorSignal(Signal::ClosingTagFound(tag))) => {
376-
if tag == "script" {
377-
found_closing_tag = true;
378-
self.consume()?;
379-
break;
380-
}
381-
}
382-
Err(e) => return Err(e),
383-
}
384-
}
385-
386-
if !found_closing_tag {
387-
return Err(ParserError::Ast(AstError::UnclosedTag(
388-
"script".to_string(),
389-
)));
390-
}
391-
392-
Ok(Node::Script(ScriptNode::Element {
393-
attributes,
394-
children,
395-
}))
396-
}
397-
398-
fn parse_style_tag_open(&mut self, s: &str) -> Result<Node, ParserError> {
399-
let parts = s.split_whitespace();
400-
401-
let mut attributes = BTreeMap::new();
402-
403-
for attr in parts {
404-
if let Some((key, value)) = parse_attribute(attr)? {
405-
attributes.insert(key, value);
406-
}
407-
}
408-
409-
let mut children = Vec::new();
410-
let mut found_closing_tag = false;
411-
412-
while !self.is_at_end() {
413-
match self.next_node() {
414-
Ok(node) => {
415-
children.push(node);
416-
}
417-
Err(ParserError::ErrorSignal(Signal::ClosingTagFound(tag))) => {
418-
if tag == "style" {
419-
found_closing_tag = true;
420-
self.consume()?;
421-
break;
422-
}
423-
}
424-
Err(e) => return Err(e),
425-
}
426-
}
427-
428-
if !found_closing_tag {
429-
return Err(ParserError::Ast(AstError::UnclosedTag("style".to_string())));
430-
}
431-
432-
Ok(Node::Style(StyleNode::Element {
433-
attributes,
434-
children,
435-
}))
436-
}
437-
438385
fn peek(&self) -> Result<Token, ParserError> {
439386
self.peek_at(0)
440387
}

crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__full_templates__parse_full.snap

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ nodes:
1818
- Style:
1919
Element:
2020
attributes:
21-
style: Boolean
2221
type:
2322
Value: text/css
2423
children:

crates/djls-template-ast/src/snapshots/djls_template_ast__parser__tests__style__parse_style.snap

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ nodes:
66
- Style:
77
Element:
88
attributes:
9-
style: Boolean
109
type:
1110
Value: text/css
1211
children:

0 commit comments

Comments
 (0)