");
- }
-
- #[test]
- fn self_closing_no_children_single_long_attr() {
- let formatted = format_element_with_self_closing_tag! {
");
- }
-
- #[test]
- fn self_closing_no_children_multi_long_attr() {
- let formatted = format_element_with_self_closing_tag! {
};
- insta::assert_snapshot!(formatted, @r###"
-
- "###);
- }
-
- #[test]
- fn self_closing_no_children_multi_attr_with_comment() {
- println!("test");
- let formatted = format_element_from_string_with_self_closing_tag!(indoc! {"
-
- "});
-
- insta::assert_snapshot!(formatted, @r###"
-
- "###);
- }
-
- #[test]
- fn self_closing_child_element() {
- let formatted = format_element_with_self_closing_tag! {
"hello"
};
- insta::assert_snapshot!(formatted, @r#"
-
- "hello"
-
- "#);
- }
-
- #[test]
- fn self_closing_child_element_single_textual() {
- let formatted = format_element_with_self_closing_tag! {
"hello"
};
- insta::assert_snapshot!(formatted, @r#"
"hello"
"#);
- }
-
- #[test]
- fn self_closing_child_element_single_textual_unquoted() {
- let formatted = format_element_from_string_with_self_closing_tag!("
hello
");
- insta::assert_snapshot!(formatted, @r###"
hello
"###);
- }
-
- #[test]
- fn self_closing_child_element_single_textual_single_attr() {
- let formatted = format_element_with_self_closing_tag! {
"hello"
};
- insta::assert_snapshot!(formatted, @r#"
"hello"
"#);
- }
-
- #[test]
- fn self_closing_child_element_single_textual_multi_attr() {
- let formatted =
- format_element_with_self_closing_tag! {
"hello"
};
- insta::assert_snapshot!(formatted, @r#"
-
- "hello"
-
- "#);
- }
-
- #[test]
- fn self_closing_child_element_two_textual() {
- let formatted =
- format_element_with_self_closing_tag! {
"The count is " {count}
};
- insta::assert_snapshot!(formatted, @r#"
"The count is " {count}
"#);
- }
-
- #[test]
- fn self_closing_child_element_many_textual() {
- let formatted = format_element_with_self_closing_tag! {
"The current count is: " {count} ". Increment by one is this: " {count + 1}
};
- insta::assert_snapshot!(formatted, @r#"
-
- "The current count is: " {count}
- ". Increment by one is this: " {count + 1}
-
- "#);
- }
-
- #[test]
- fn self_closing_child_element_two_textual_unquoted() {
- let formatted = format_element_from_string_with_self_closing_tag! { "
The count is {count}.
" };
- insta::assert_snapshot!(formatted, @r#"
The count is {count}.
"#);
- }
-
- #[test]
- fn self_closing_child_element_two_textual_unquoted_no_trailingspace() {
- let formatted =
- format_element_from_string_with_self_closing_tag! { "
The count is{count}
" };
- insta::assert_snapshot!(formatted, @r#"
The count is{count}
"#);
- }
-
- #[test]
- fn self_closing_child_element_many_textual_unquoted() {
- let formatted = format_element_from_string_with_self_closing_tag! { "
The current count is: {count}. Increment by one is this: {count + 1}
" };
- insta::assert_snapshot!(formatted, @r###"
-
- The current count is: {count}. Increment by one is this:
- {count + 1}
-
- "###);
- }
- // view! {
Something: {something} .
}
-
- #[test]
- fn self_closing_html_unquoted_text() {
- let formatted =
- format_element_from_string_with_self_closing_tag!(r##"
Unquoted text
"##);
- insta::assert_snapshot!(formatted, @"
Unquoted text
");
- }
-
- #[test]
- fn self_closing_html_unquoted_text_with_surrounding_spaces() {
- let formatted = format_element_from_string_with_self_closing_tag!(
- r##"
Unquoted text with spaces
"##
- );
- insta::assert_snapshot!(formatted, @"
Unquoted text with spaces
");
+ fn self_closing_void_element_no_children_separate_closing_tag() {
+ let formatted = format_element_with_self_closing_tag! { < input >< / input > };
+ insta::assert_snapshot!(formatted, @"
");
}
#[test]
- fn self_closing_html_unquoted_text_multiline() {
- let formatted = format_element_from_string_with_self_closing_tag!(indoc! {"
-
- Unquoted text
- with spaces
-
- "});
-
- insta::assert_snapshot!(formatted, @r###"
-
- Unquoted text
- with spaces
-
"###);
+ fn self_closing_void_element_no_children_self_closing_tag() {
+ let formatted = format_element_with_self_closing_tag! { < input / > };
+ insta::assert_snapshot!(formatted, @"
");
}
#[test]
- fn self_closing_single_empty_line() {
- let formatted = format_element_from_string_with_self_closing_tag!(indoc! {r#"
-
-
-
-
-
- "#});
-
- insta::assert_snapshot!(formatted, @r###"
-
-
-
-
-
- "###);
+ fn self_closing_non_void_element_with_child() {
+ let formatted = format_element_with_self_closing_tag! { < div > "Child" < / div > };
+ insta::assert_snapshot!(formatted, @r#"
"Child"
"#);
}
#[test]
- fn self_closing_multiple_empty_lines() {
- let formatted = format_element_from_string_with_self_closing_tag!(indoc! {r#"
-
-
-
-
-
-
-
- "#});
-
- insta::assert_snapshot!(formatted, @r###"
-
-
-
-
-
- "###);
+ fn self_closing_non_void_element_no_children_separate_closing_tag() {
+ let formatted = format_element_with_self_closing_tag! { < div >< / div > };
+ insta::assert_snapshot!(formatted, @"
");
}
#[test]
- fn self_closing_surrounded_by_empty_lines() {
- let formatted = format_element_from_string_with_self_closing_tag!(indoc! {r#"
-
-
-
-
-
-
- "#});
-
- insta::assert_snapshot!(formatted, @r###"
-
-
-
-
- "###);
+ fn self_closing_non_void_element_no_children_self_closing_tag() {
+ let formatted = format_element_with_self_closing_tag! { < div / > };
+ insta::assert_snapshot!(formatted, @"
");
}
- #[test]
- fn self_closing_other_test() {
- let formatted = format_element_from_string_with_self_closing_tag!(indoc! {r#"
-
-
-
- "Sign in with google"
-
-
- "#});
-
- insta::assert_snapshot!(formatted, @r#"
-
-
-
- "Sign in with google"
-
-
- "#);
- }
+ // Non Self Closing Tag
+ // TODO uncomment when macro is properly working
+
+ // #[test]
+ // fn non_self_closing_void_element_no_children_separate_closing_tag() {
+ // let formatted = format_element_with_self_closing_tag! { < input >< / input > };
+ // insta::assert_snapshot!(formatted, @"
");
+ // }
+
+ // #[test]
+ // fn non_self_closing_void_element_no_children_self_closing_tag() {
+ // let formatted = format_element_with_self_closing_tag! { < input / > };
+ // insta::assert_snapshot!(formatted, @"
");
+ // }
+
+ // #[test]
+ // fn non_self_closing_non_void_element_with_child() {
+ // let formatted = format_element_with_self_closing_tag! { < div > "Child" < / div > };
+ // insta::assert_snapshot!(formatted, @r#"
"Hello"
"#);
+ // }
+
+ // #[test]
+ // fn non_self_closing_non_void_element_no_children_separate_closing_tag() {
+ // let formatted = format_element_with_self_closing_tag! { < div >< / div > };
+ // insta::assert_snapshot!(formatted, @"
");
+ // }
+
+ // #[test]
+ // fn non_self_closing_non_void_element_no_children_self_closing_tag() {
+ // let formatted = format_element_with_self_closing_tag! { < div / > };
+ // insta::assert_snapshot!(formatted, @"
");
+ // }
}
diff --git a/formatter/src/formatter/mod.rs b/formatter/src/formatter/mod.rs
index 9d69ba6..ca5385a 100644
--- a/formatter/src/formatter/mod.rs
+++ b/formatter/src/formatter/mod.rs
@@ -19,6 +19,16 @@ pub use mac::{ParentIndent, ViewMacro};
use serde::Deserialize;
use serde::Serialize;
+#[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)]
+pub enum ClosingTagStyle {
+ /// Preserve the original closing tag style (self-closing or a separate closing tag)
+ Preserve,
+ /// Self closing tag for elements with no children: `
` formats to `
`
+ SelfClosing,
+ /// Separate closing tag for elements with no children: `
` formats to `
`
+ NonSelfClosing,
+}
+
#[derive(Clone, Copy, Debug, PartialEq, Deserialize, Serialize)]
pub enum AttributeValueBraceStyle {
Always,
@@ -73,8 +83,8 @@ pub struct FormatterSettings {
/// Determines placement of braces around single expression attribute values
pub attr_value_brace_style: AttributeValueBraceStyle,
- /// Allows non void HTML tags like div to be self closing. If set to true,
will no longer format to
- pub allow_non_void_self_closing_tags: bool,
+ /// Preferred style for closing tags (self-closing or not) when a non-void element has no children
+ pub closing_tag_style: ClosingTagStyle,
/// Determines macros to be formatted. Default: leptos::view, view
pub macro_names: Vec
,
@@ -91,7 +101,7 @@ impl Default for FormatterSettings {
attr_value_brace_style: AttributeValueBraceStyle::WhenRequired,
indentation_style: IndentationStyle::Auto,
newline_style: NewlineStyle::Auto,
- allow_non_void_self_closing_tags: false,
+ closing_tag_style: ClosingTagStyle::Preserve,
macro_names: vec!["leptos::view".to_string(), "view".to_string()],
attr_values: HashMap::new(),
}
From bccf3696b72bb9df456385326dbf2a7bb3e5059c Mon Sep 17 00:00:00 2001
From: V4ldum <56064897+V4ldum@users.noreply.github.com>
Date: Thu, 11 Jul 2024 18:34:09 +0200
Subject: [PATCH 5/8] Add space before "/>" & Update test macros and
is_self_closing behaviour
---
formatter/src/formatter/element.rs | 244 +++++++++++++++++------------
1 file changed, 143 insertions(+), 101 deletions(-)
diff --git a/formatter/src/formatter/element.rs b/formatter/src/formatter/element.rs
index 2ad20a0..719855d 100644
--- a/formatter/src/formatter/element.rs
+++ b/formatter/src/formatter/element.rs
@@ -6,26 +6,25 @@ use syn::spanned::Spanned;
impl Formatter<'_> {
pub fn element(&mut self, element: &NodeElement) {
let name = element.name().to_string();
- let is_void = is_void_element(&name, !element.children.is_empty());
- let is_self_closing = is_self_closing(is_void, self.settings.closing_tag_style);
- let is_empty = element.children.is_empty();
+ let is_self_closing = is_self_closing(element, &name, self.settings.closing_tag_style);
- self.opening_tag(element, is_self_closing, is_empty);
+ self.opening_tag(element, is_self_closing);
- if !(is_self_closing && is_empty) {
+ if !is_self_closing {
self.children(&element.children, element.attributes().len());
self.flush_comments(element.close_tag.span().end().line - 1);
self.closing_tag(element)
}
}
- fn opening_tag(&mut self, element: &NodeElement, is_self_closing: bool, is_empty: bool) {
+ fn opening_tag(&mut self, element: &NodeElement, is_self_closing: bool) {
self.printer.word("<");
self.node_name(&element.open_tag.name);
self.attributes(element.attributes());
- if is_self_closing && is_empty {
+ if is_self_closing {
+ self.printer.nbsp();
self.printer.word("/>");
} else {
self.printer.word(">")
@@ -117,33 +116,41 @@ impl Formatter<'_> {
}
}
-fn is_void_element(name: &str, has_children: bool) -> bool {
- if name.chars().next().unwrap().is_uppercase() {
- !has_children
- } else {
- matches!(
- name,
- "area"
- | "base"
- | "br"
- | "col"
- | "embed"
- | "hr"
- | "img"
- | "input"
- | "link"
- | "meta"
- | "param"
- | "source"
- | "track"
- | "wbr"
- )
- }
+fn is_void_element(name: &str) -> bool {
+ matches!(
+ name,
+ "area"
+ | "base"
+ | "br"
+ | "col"
+ | "embed"
+ | "hr"
+ | "img"
+ | "input"
+ | "link"
+ | "meta"
+ | "param"
+ | "source"
+ | "track"
+ | "wbr"
+ )
}
-fn is_self_closing(is_void: bool, closing_tag_style: ClosingTagStyle) -> bool {
- closing_tag_style == ClosingTagStyle::SelfClosing
- || closing_tag_style == ClosingTagStyle::Preserve && is_void
+fn is_self_closing(element: &NodeElement, name: &str, closing_tag_style: ClosingTagStyle) -> bool {
+ if !element.children.is_empty() {
+ return false;
+ }
+
+ if is_void_element(name) {
+ return true;
+ };
+
+ // At this point, it must be a non-void element that has no children
+ match closing_tag_style {
+ ClosingTagStyle::Preserve => element.close_tag.is_none(),
+ ClosingTagStyle::SelfClosing => true,
+ ClosingTagStyle::NonSelfClosing => false,
+ }
}
#[cfg(test)]
@@ -158,20 +165,28 @@ mod tests {
macro_rules! format_element {
($($tt:tt)*) => {{
- let element = element! { $($tt)* };
- format_with(FormatterSettings { max_width: 40, ..Default::default() }, |formatter| {
- formatter.element(&element)
- })
+ format_element_with!(Default::default(), $($tt)*)
}};
}
- macro_rules! format_element_with_self_closing_tag {
- ($($tt:tt)*) => {{
+
+ macro_rules! format_element_with_closing_style {
+ ($style:expr, $($tt:tt)*) => {{
+ format_element_with!(FormatterSettings {
+ closing_tag_style: $style,
+ ..Default::default()
+ }, $($tt)*)
+ }};
+ }
+
+ macro_rules! format_element_with {
+ ($settings:expr, $($tt:tt)*) => {{
let element = element! { $($tt)* };
- format_with(FormatterSettings { max_width: 40, closing_tag_style: ClosingTagStyle::SelfClosing, ..Default::default() }, |formatter| {
+ format_with(FormatterSettings { max_width: 40, ..$settings }, |formatter| {
formatter.element(&element)
})
}};
}
+
macro_rules! format_element_from_string {
($val:expr) => {{
format_element_from_string(
@@ -349,17 +364,17 @@ mod tests {
fn single_empty_line() {
let formatted = format_element_from_string!(indoc! {r#"
-
+
-
+
"#});
insta::assert_snapshot!(formatted, @r###"
-
+
-
+
"###);
}
@@ -368,19 +383,19 @@ mod tests {
fn multiple_empty_lines() {
let formatted = format_element_from_string!(indoc! {r#"
-
+
-
+
"#});
insta::assert_snapshot!(formatted, @r###"
-
+
-
+
"###);
}
@@ -390,16 +405,16 @@ mod tests {
let formatted = format_element_from_string!(indoc! {r#"
-
-
+
+
"#});
insta::assert_snapshot!(formatted, @r###"
-
-
+
+
"###);
}
@@ -427,68 +442,95 @@ mod tests {
"#);
}
- // Self Closing Tag
+ // Closing Tags Behaviour
#[test]
- fn self_closing_void_element_no_children_separate_closing_tag() {
- let formatted = format_element_with_self_closing_tag! { < input >< / input > };
- insta::assert_snapshot!(formatted, @"");
+ fn void_element_no_children_separate_closing_tag() {
+ let preserve_formatted =
+ format_element_with_closing_style! { ClosingTagStyle::Preserve, < input >< / input > };
+ let self_closing_formatted = format_element_with_closing_style! { ClosingTagStyle::SelfClosing, < input >< / input > };
+ let non_self_closing_formatted = format_element_with_closing_style! { ClosingTagStyle::NonSelfClosing, < input >< / input > };
+
+ insta::assert_snapshot!(preserve_formatted, @"");
+ insta::assert_snapshot!(self_closing_formatted, @"");
+ insta::assert_snapshot!(non_self_closing_formatted, @"");
}
#[test]
- fn self_closing_void_element_no_children_self_closing_tag() {
- let formatted = format_element_with_self_closing_tag! { < input / > };
- insta::assert_snapshot!(formatted, @"");
+ fn void_element_no_children_self_closing_tag_one_line() {
+ let preserve_formatted =
+ format_element_with_closing_style! { ClosingTagStyle::Preserve, < input / > };
+ let self_closing_formatted =
+ format_element_with_closing_style! { ClosingTagStyle::SelfClosing, < input / > };
+ let non_self_closing_formatted =
+ format_element_with_closing_style! { ClosingTagStyle::NonSelfClosing, < input / > };
+
+ insta::assert_snapshot!(preserve_formatted, @"");
+ insta::assert_snapshot!(self_closing_formatted, @"");
+ insta::assert_snapshot!(non_self_closing_formatted, @"");
}
#[test]
- fn self_closing_non_void_element_with_child() {
- let formatted = format_element_with_self_closing_tag! { < div > "Child" < / div > };
- insta::assert_snapshot!(formatted, @r#""Child"
"#);
+ fn void_element_no_children_self_closing_tag_multi_line() {
+ let preserve_formatted = format_element_with_closing_style! { ClosingTagStyle::Preserve, < input key=1 class="veryveryvery longlonglong attributesattributesattributes listlistlist" / > };
+ let self_closing_formatted = format_element_with_closing_style! { ClosingTagStyle::SelfClosing, < input key=1 class="veryveryvery longlonglong attributesattributesattributes listlistlist" / > };
+ let non_self_closing_formatted = format_element_with_closing_style! { ClosingTagStyle::NonSelfClosing, < input key=1 class="veryveryvery longlonglong attributesattributesattributes listlistlist" / > };
+
+ insta::assert_snapshot!(preserve_formatted, @r#"
+
+ "#);
+ insta::assert_snapshot!(self_closing_formatted, @r#"
+
+ "#);
+ insta::assert_snapshot!(non_self_closing_formatted, @r#"
+
+ "#);
}
#[test]
- fn self_closing_non_void_element_no_children_separate_closing_tag() {
- let formatted = format_element_with_self_closing_tag! { < div >< / div > };
- insta::assert_snapshot!(formatted, @"");
+ fn non_void_element_with_child() {
+ let preserve_formatted = format_element_with_closing_style! { ClosingTagStyle::Preserve, < div > "Child" < / div > };
+ let self_closing_formatted = format_element_with_closing_style! { ClosingTagStyle::SelfClosing, < div > "Child" < / div > };
+ let non_self_closing_formatted = format_element_with_closing_style! { ClosingTagStyle::NonSelfClosing, < div > "Child" < / div > };
+
+ insta::assert_snapshot!(preserve_formatted, @r#""Child"
"#);
+ insta::assert_snapshot!(self_closing_formatted, @r#""Child"
"#);
+ insta::assert_snapshot!(non_self_closing_formatted, @r#""Child"
"#);
+ }
+
+ #[test]
+ fn non_void_element_no_children_separate_closing_tag() {
+ let preserve_formatted =
+ format_element_with_closing_style! { ClosingTagStyle::Preserve, < div >< / div > };
+ let self_closing_formatted =
+ format_element_with_closing_style! { ClosingTagStyle::SelfClosing, < div >< / div > };
+ let non_self_closing_formatted = format_element_with_closing_style! { ClosingTagStyle::NonSelfClosing, < div >< / div > };
+
+ insta::assert_snapshot!(preserve_formatted, @"");
+ insta::assert_snapshot!(self_closing_formatted, @"");
+ insta::assert_snapshot!(non_self_closing_formatted, @"");
}
#[test]
- fn self_closing_non_void_element_no_children_self_closing_tag() {
- let formatted = format_element_with_self_closing_tag! { < div / > };
- insta::assert_snapshot!(formatted, @"");
- }
-
- // Non Self Closing Tag
- // TODO uncomment when macro is properly working
-
- // #[test]
- // fn non_self_closing_void_element_no_children_separate_closing_tag() {
- // let formatted = format_element_with_self_closing_tag! { < input >< / input > };
- // insta::assert_snapshot!(formatted, @"");
- // }
-
- // #[test]
- // fn non_self_closing_void_element_no_children_self_closing_tag() {
- // let formatted = format_element_with_self_closing_tag! { < input / > };
- // insta::assert_snapshot!(formatted, @"");
- // }
-
- // #[test]
- // fn non_self_closing_non_void_element_with_child() {
- // let formatted = format_element_with_self_closing_tag! { < div > "Child" < / div > };
- // insta::assert_snapshot!(formatted, @r#""Hello"
"#);
- // }
-
- // #[test]
- // fn non_self_closing_non_void_element_no_children_separate_closing_tag() {
- // let formatted = format_element_with_self_closing_tag! { < div >< / div > };
- // insta::assert_snapshot!(formatted, @"");
- // }
-
- // #[test]
- // fn non_self_closing_non_void_element_no_children_self_closing_tag() {
- // let formatted = format_element_with_self_closing_tag! { < div / > };
- // insta::assert_snapshot!(formatted, @"");
- // }
+ fn non_void_element_no_children_self_closing_tag() {
+ let preserve_formatted =
+ format_element_with_closing_style! { ClosingTagStyle::Preserve, < div / > };
+ let self_closing_formatted =
+ format_element_with_closing_style! { ClosingTagStyle::SelfClosing, < div / > };
+ let non_self_closing_formatted =
+ format_element_with_closing_style! { ClosingTagStyle::NonSelfClosing, < div / > };
+
+ insta::assert_snapshot!(preserve_formatted, @"");
+ insta::assert_snapshot!(self_closing_formatted, @"");
+ insta::assert_snapshot!(non_self_closing_formatted, @"");
+ }
}
From b2fa0a2c6ca620831f36a87c18cbe8a0a877ac24 Mon Sep 17 00:00:00 2001
From: V4ldum <56064897+V4ldum@users.noreply.github.com>
Date: Thu, 11 Jul 2024 18:40:29 +0200
Subject: [PATCH 6/8] Fix conflict
---
formatter/src/formatter/element.rs | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/formatter/src/formatter/element.rs b/formatter/src/formatter/element.rs
index 719855d..067ee92 100644
--- a/formatter/src/formatter/element.rs
+++ b/formatter/src/formatter/element.rs
@@ -442,6 +442,12 @@ mod tests {
"#);
}
+ #[test]
+ fn with_generics() {
+ let formatted = format_element! { /> };
+ insta::assert_snapshot!(formatted, @"/>");
+ }
+
// Closing Tags Behaviour
#[test]
From 0b121b8474d3d01002026a64aac6348dff93a565 Mon Sep 17 00:00:00 2001
From: V4ldum <56064897+V4ldum@users.noreply.github.com>
Date: Thu, 11 Jul 2024 18:44:09 +0200
Subject: [PATCH 7/8] Update new test
---
formatter/src/formatter/element.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/formatter/src/formatter/element.rs b/formatter/src/formatter/element.rs
index 841cc5d..1df4cb0 100644
--- a/formatter/src/formatter/element.rs
+++ b/formatter/src/formatter/element.rs
@@ -446,7 +446,7 @@ mod tests {
#[test]
fn with_generics() {
let formatted = format_element! { /> };
- insta::assert_snapshot!(formatted, @"/>");
+ insta::assert_snapshot!(formatted, @" />");
}
// Closing Tags Behaviour
From 4253ccf73599210cb11041d47a12f01a2bf377fe Mon Sep 17 00:00:00 2001
From: V4ldum <56064897+V4ldum@users.noreply.github.com>
Date: Sat, 13 Jul 2024 16:32:47 +0200
Subject: [PATCH 8/8] Fix space for self closing tag & add test for formatting
with one attribute
---
formatter/src/formatter/element.rs | 68 ++++++++++++++++++++----------
1 file changed, 46 insertions(+), 22 deletions(-)
diff --git a/formatter/src/formatter/element.rs b/formatter/src/formatter/element.rs
index 1df4cb0..df811dc 100644
--- a/formatter/src/formatter/element.rs
+++ b/formatter/src/formatter/element.rs
@@ -22,10 +22,9 @@ impl Formatter<'_> {
self.node_name(&element.open_tag.name);
leptosfmt_prettyplease::unparse_generics(&element.open_tag.generics, self.printer);
- self.attributes(element.attributes());
+ self.attributes(element.attributes(), is_self_closing);
if is_self_closing {
- self.printer.nbsp();
self.printer.word("/>");
} else {
self.printer.word(">")
@@ -38,31 +37,43 @@ impl Formatter<'_> {
self.printer.word(">");
}
- fn attributes(&mut self, attributes: &[NodeAttribute]) {
- if attributes.is_empty() {
- return;
- }
+ fn attributes(&mut self, attributes: &[NodeAttribute], trailing_space: bool) {
+ match attributes {
+ [] => {
+ if trailing_space {
+ self.printer.nbsp();
+ }
+ }
+ [attribute] => {
+ self.printer.cbox(0);
+ self.printer.nbsp();
+ self.attribute(attribute);
- if let [attribute] = attributes {
- self.printer.cbox(0);
- self.printer.nbsp();
- self.attribute(attribute);
- self.printer.end();
- } else {
- self.printer.cbox_indent();
- self.printer.space();
+ if trailing_space {
+ self.printer.nbsp();
+ }
+ self.printer.end();
+ }
+ _ => {
+ self.printer.cbox_indent();
+ self.printer.space();
- let mut iter = attributes.iter().peekable();
- while let Some(attr) = iter.next() {
- self.attribute(attr);
+ let mut iter = attributes.iter().peekable();
+ while let Some(attr) = iter.next() {
+ self.attribute(attr);
- if iter.peek().is_some() {
- self.printer.space()
+ if iter.peek().is_some() {
+ self.printer.space()
+ }
}
- }
- self.printer.zerobreak();
- self.printer.end_dedent();
+ if trailing_space {
+ self.printer.space(); // Only results in a space if the consistent box didn't break
+ } else {
+ self.printer.zerobreak();
+ }
+ self.printer.end_dedent();
+ }
}
}
@@ -477,6 +488,19 @@ mod tests {
insta::assert_snapshot!(non_self_closing_formatted, @"");
}
+ #[test]
+ fn void_element_no_children_self_closing_tag_single_attr() {
+ let preserve_formatted =
+ format_element_with_closing_style! { ClosingTagStyle::Preserve, < input key=1 / > };
+ let self_closing_formatted =
+ format_element_with_closing_style! { ClosingTagStyle::SelfClosing, < input key=1 / > };
+ let non_self_closing_formatted = format_element_with_closing_style! { ClosingTagStyle::NonSelfClosing, < input key=1 / > };
+
+ insta::assert_snapshot!(preserve_formatted, @"");
+ insta::assert_snapshot!(self_closing_formatted, @"");
+ insta::assert_snapshot!(non_self_closing_formatted, @"");
+ }
+
#[test]
fn void_element_no_children_self_closing_tag_multi_line() {
let preserve_formatted = format_element_with_closing_style! { ClosingTagStyle::Preserve, < input key=1 class="veryveryvery longlonglong attributesattributesattributes listlistlist" / > };