From a336f885d7da952acf7af5a23bf94655f7373abf Mon Sep 17 00:00:00 2001 From: Carson McManus Date: Wed, 4 Sep 2024 11:55:30 -0400 Subject: [PATCH] feat(format/html): attribute formatting --- .../src/html/auxiliary/attribute.rs | 8 +++-- .../auxiliary/attribute_initializer_clause.rs | 8 +++-- .../src/html/auxiliary/opening_element.rs | 14 +++----- .../html/auxiliary/self_closing_element.rs | 3 +- .../src/html/auxiliary/string.rs | 33 +++++++++++++++++-- .../src/html/lists/attribute_list.rs | 16 ++++++++- .../tests/specs/attributes-break.html | 1 + .../tests/specs/attributes-break.html.snap | 33 +++++++++++++++++++ .../tests/specs/attributes-no-break.html | 1 + .../tests/specs/attributes-no-break.html.snap | 28 ++++++++++++++++ .../tests/specs/attributes-self-closing.html | 1 + .../specs/attributes-self-closing.html.snap | 28 ++++++++++++++++ .../tests/specs/self-closing.html | 1 + .../tests/specs/self-closing.html.snap | 28 ++++++++++++++++ 14 files changed, 183 insertions(+), 20 deletions(-) create mode 100644 crates/biome_html_formatter/tests/specs/attributes-break.html create mode 100644 crates/biome_html_formatter/tests/specs/attributes-break.html.snap create mode 100644 crates/biome_html_formatter/tests/specs/attributes-no-break.html create mode 100644 crates/biome_html_formatter/tests/specs/attributes-no-break.html.snap create mode 100644 crates/biome_html_formatter/tests/specs/attributes-self-closing.html create mode 100644 crates/biome_html_formatter/tests/specs/attributes-self-closing.html.snap create mode 100644 crates/biome_html_formatter/tests/specs/self-closing.html create mode 100644 crates/biome_html_formatter/tests/specs/self-closing.html.snap diff --git a/crates/biome_html_formatter/src/html/auxiliary/attribute.rs b/crates/biome_html_formatter/src/html/auxiliary/attribute.rs index dcaaff5ad42d..b93e2497a169 100644 --- a/crates/biome_html_formatter/src/html/auxiliary/attribute.rs +++ b/crates/biome_html_formatter/src/html/auxiliary/attribute.rs @@ -1,10 +1,12 @@ use crate::prelude::*; -use biome_html_syntax::HtmlAttribute; -use biome_rowan::AstNode; +use biome_formatter::write; +use biome_html_syntax::{HtmlAttribute, HtmlAttributeFields}; #[derive(Debug, Clone, Default)] pub(crate) struct FormatHtmlAttribute; impl FormatNodeRule for FormatHtmlAttribute { fn fmt_fields(&self, node: &HtmlAttribute, f: &mut HtmlFormatter) -> FormatResult<()> { - format_verbatim_node(node.syntax()).fmt(f) + let HtmlAttributeFields { name, initializer } = node.as_fields(); + + write![f, [name.format(), initializer.format()]] } } diff --git a/crates/biome_html_formatter/src/html/auxiliary/attribute_initializer_clause.rs b/crates/biome_html_formatter/src/html/auxiliary/attribute_initializer_clause.rs index 59f6f4b03a06..77e6a0941be3 100644 --- a/crates/biome_html_formatter/src/html/auxiliary/attribute_initializer_clause.rs +++ b/crates/biome_html_formatter/src/html/auxiliary/attribute_initializer_clause.rs @@ -1,6 +1,6 @@ use crate::prelude::*; -use biome_html_syntax::HtmlAttributeInitializerClause; -use biome_rowan::AstNode; +use biome_formatter::write; +use biome_html_syntax::{HtmlAttributeInitializerClause, HtmlAttributeInitializerClauseFields}; #[derive(Debug, Clone, Default)] pub(crate) struct FormatHtmlAttributeInitializerClause; impl FormatNodeRule for FormatHtmlAttributeInitializerClause { @@ -9,6 +9,8 @@ impl FormatNodeRule for FormatHtmlAttributeIniti node: &HtmlAttributeInitializerClause, f: &mut HtmlFormatter, ) -> FormatResult<()> { - format_verbatim_node(node.syntax()).fmt(f) + let HtmlAttributeInitializerClauseFields { eq_token, value } = node.as_fields(); + + write![f, [eq_token.format(), value.format()]] } } diff --git a/crates/biome_html_formatter/src/html/auxiliary/opening_element.rs b/crates/biome_html_formatter/src/html/auxiliary/opening_element.rs index 81e29996ea5d..1ef107860f6a 100644 --- a/crates/biome_html_formatter/src/html/auxiliary/opening_element.rs +++ b/crates/biome_html_formatter/src/html/auxiliary/opening_element.rs @@ -12,15 +12,11 @@ impl FormatNodeRule for FormatHtmlOpeningElement { r_angle_token, } = node.as_fields(); - write!( - f, - [ - l_angle_token.format(), - name.format(), - attributes.format(), - r_angle_token.format(), - ] - )?; + write!(f, [l_angle_token.format(), name.format(),])?; + if attributes.len() > 0 { + write!(f, [space(), attributes.format()])? + } + write!(f, [r_angle_token.format()])?; Ok(()) } diff --git a/crates/biome_html_formatter/src/html/auxiliary/self_closing_element.rs b/crates/biome_html_formatter/src/html/auxiliary/self_closing_element.rs index ce6ff35ee041..5723b77ea522 100644 --- a/crates/biome_html_formatter/src/html/auxiliary/self_closing_element.rs +++ b/crates/biome_html_formatter/src/html/auxiliary/self_closing_element.rs @@ -18,8 +18,9 @@ impl FormatNodeRule for FormatHtmlSelfClosingElement { [ l_angle_token.format(), name.format(), + space(), attributes.format(), - soft_line_break_or_space(), + space(), slash_token.format(), r_angle_token.format() ] diff --git a/crates/biome_html_formatter/src/html/auxiliary/string.rs b/crates/biome_html_formatter/src/html/auxiliary/string.rs index c216058dd65e..f4377e426144 100644 --- a/crates/biome_html_formatter/src/html/auxiliary/string.rs +++ b/crates/biome_html_formatter/src/html/auxiliary/string.rs @@ -1,10 +1,37 @@ use crate::prelude::*; -use biome_html_syntax::HtmlString; -use biome_rowan::AstNode; +use biome_formatter::{format_args, write}; +use biome_html_syntax::{HtmlString, HtmlStringFields}; #[derive(Debug, Clone, Default)] pub(crate) struct FormatHtmlString; impl FormatNodeRule for FormatHtmlString { fn fmt_fields(&self, node: &HtmlString, f: &mut HtmlFormatter) -> FormatResult<()> { - format_verbatim_node(node.syntax()).fmt(f) + let HtmlStringFields { value_token } = node.as_fields(); + + // Prettier always uses double quotes for HTML strings, regardless of configuration. + if let Ok(value) = value_token.as_ref() { + let value_text = value.text().trim(); + + if !(value_text.starts_with('"') && value_text.ends_with('"')) { + let range = if value_text.starts_with('\'') && value_text.ends_with('\'') { + value.text_range().add_start(1.into()).sub_end(1.into()) + } else { + value.text_range() + }; + write!( + f, + [format_replaced( + value, + &group(&format_args![ + text("\""), + located_token_text(value, range), + text("\""), + ]) + )] + )?; + return Ok(()); + } + } + + write!(f, [value_token.format()]) } } diff --git a/crates/biome_html_formatter/src/html/lists/attribute_list.rs b/crates/biome_html_formatter/src/html/lists/attribute_list.rs index 90c2b0044ac1..595cc92eda49 100644 --- a/crates/biome_html_formatter/src/html/lists/attribute_list.rs +++ b/crates/biome_html_formatter/src/html/lists/attribute_list.rs @@ -1,10 +1,24 @@ use crate::prelude::*; +use biome_formatter::{write, AttributePosition}; use biome_html_syntax::HtmlAttributeList; #[derive(Debug, Clone, Default)] pub(crate) struct FormatHtmlAttributeList; impl FormatRule for FormatHtmlAttributeList { type Context = HtmlFormatContext; fn fmt(&self, node: &HtmlAttributeList, f: &mut HtmlFormatter) -> FormatResult<()> { - f.join().entries(node.iter().formatted()).finish() + let line_break = if f.options().attribute_position() == AttributePosition::Multiline { + hard_line_break() + } else { + soft_line_break_or_space() + }; + + write!( + f, + [&group(&soft_block_indent(&format_with(|f| { + f.join_with(&line_break) + .entries(node.iter().formatted()) + .finish() + })))] + ) } } diff --git a/crates/biome_html_formatter/tests/specs/attributes-break.html b/crates/biome_html_formatter/tests/specs/attributes-break.html new file mode 100644 index 000000000000..aa54f355da38 --- /dev/null +++ b/crates/biome_html_formatter/tests/specs/attributes-break.html @@ -0,0 +1 @@ +
diff --git a/crates/biome_html_formatter/tests/specs/attributes-break.html.snap b/crates/biome_html_formatter/tests/specs/attributes-break.html.snap new file mode 100644 index 000000000000..befbd8c3b1cb --- /dev/null +++ b/crates/biome_html_formatter/tests/specs/attributes-break.html.snap @@ -0,0 +1,33 @@ +--- +source: crates/biome_formatter_test/src/snapshot_builder.rs +info: attributes-break.html +--- +# Input + +```html +
+ +``` + + +============================= + +# Outputs + +## Output 1 + +----- +Indent style: Tab +Indent width: 2 +Line ending: LF +Line width: 80 +Attribute Position: Auto +----- + +```html +
``` diff --git a/crates/biome_html_formatter/tests/specs/attributes-no-break.html b/crates/biome_html_formatter/tests/specs/attributes-no-break.html new file mode 100644 index 000000000000..8a1e90444217 --- /dev/null +++ b/crates/biome_html_formatter/tests/specs/attributes-no-break.html @@ -0,0 +1 @@ +
diff --git a/crates/biome_html_formatter/tests/specs/attributes-no-break.html.snap b/crates/biome_html_formatter/tests/specs/attributes-no-break.html.snap new file mode 100644 index 000000000000..de5bb0ce15af --- /dev/null +++ b/crates/biome_html_formatter/tests/specs/attributes-no-break.html.snap @@ -0,0 +1,28 @@ +--- +source: crates/biome_formatter_test/src/snapshot_builder.rs +info: attributes-no-break.html +--- +# Input + +```html +
+ +``` + + +============================= + +# Outputs + +## Output 1 + +----- +Indent style: Tab +Indent width: 2 +Line ending: LF +Line width: 80 +Attribute Position: Auto +----- + +```html +
``` diff --git a/crates/biome_html_formatter/tests/specs/attributes-self-closing.html b/crates/biome_html_formatter/tests/specs/attributes-self-closing.html new file mode 100644 index 000000000000..93807347f72f --- /dev/null +++ b/crates/biome_html_formatter/tests/specs/attributes-self-closing.html @@ -0,0 +1 @@ + diff --git a/crates/biome_html_formatter/tests/specs/attributes-self-closing.html.snap b/crates/biome_html_formatter/tests/specs/attributes-self-closing.html.snap new file mode 100644 index 000000000000..8bd93c746836 --- /dev/null +++ b/crates/biome_html_formatter/tests/specs/attributes-self-closing.html.snap @@ -0,0 +1,28 @@ +--- +source: crates/biome_formatter_test/src/snapshot_builder.rs +info: attributes-self-closing.html +--- +# Input + +```html + + +``` + + +============================= + +# Outputs + +## Output 1 + +----- +Indent style: Tab +Indent width: 2 +Line ending: LF +Line width: 80 +Attribute Position: Auto +----- + +```html +``` diff --git a/crates/biome_html_formatter/tests/specs/self-closing.html b/crates/biome_html_formatter/tests/specs/self-closing.html new file mode 100644 index 000000000000..3fc714a368c2 --- /dev/null +++ b/crates/biome_html_formatter/tests/specs/self-closing.html @@ -0,0 +1 @@ +
diff --git a/crates/biome_html_formatter/tests/specs/self-closing.html.snap b/crates/biome_html_formatter/tests/specs/self-closing.html.snap new file mode 100644 index 000000000000..0cf197454624 --- /dev/null +++ b/crates/biome_html_formatter/tests/specs/self-closing.html.snap @@ -0,0 +1,28 @@ +--- +source: crates/biome_formatter_test/src/snapshot_builder.rs +info: self-closing.html +--- +# Input + +```html +
+ +``` + + +============================= + +# Outputs + +## Output 1 + +----- +Indent style: Tab +Indent width: 2 +Line ending: LF +Line width: 80 +Attribute Position: Auto +----- + +```html +
```