Skip to content

Commit

Permalink
feat(format/html): implement bracketSameLine (#4968)
Browse files Browse the repository at this point in the history
  • Loading branch information
dyc3 authored Feb 2, 2025
1 parent 703bff0 commit 93dda40
Show file tree
Hide file tree
Showing 8 changed files with 232 additions and 32 deletions.
30 changes: 23 additions & 7 deletions crates/biome_html_formatter/src/html/auxiliary/opening_element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,30 @@ impl FormatNodeRule<HtmlOpeningElement> for FormatHtmlOpeningElement {
r_angle_token,
} = node.as_fields();

let bracket_same_line = f.options().bracket_same_line().value();
write!(f, [l_angle_token.format(), name.format()])?;
if attributes.len() > 0 {
write!(f, [space(), attributes.format()])?
}
// When these tokens are borrowed, they are managed by the sibling `HtmlElementList` formatter.
if !self.r_angle_is_borrowed {
write!(f, [r_angle_token.format()])?;
}

let attr_group_id = f.group_id("element-attr-group-id");
write!(
f,
[&group(&format_with(|f| {
attributes.format().fmt(f)?;

// Whitespace sensitivity takes precedence over bracketSameLine for correctness.
//
// The r_angle is placed inside this group because prettier always includes this token
// in the same group as the attributes, unless the token is being borrowed.
// When these tokens are borrowed, they are managed by the sibling `HtmlElementList` formatter.
if !bracket_same_line {
write!(f, [soft_line_break()])?;
}
if !self.r_angle_is_borrowed {
write!(f, [r_angle_token.format()])?;
}
Ok(())
}))
.with_group_id(Some(attr_group_id))]
)?;

Ok(())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,42 @@ impl FormatNodeRule<HtmlSelfClosingElement> for FormatHtmlSelfClosingElement {
slash_token,
r_angle_token,
} = node.as_fields();
let bracket_same_line = f.options().bracket_same_line().value();

write!(f, [l_angle_token.format(), name.format(), space()])?;

let attr_group_id = f.group_id("element-attr-group-id");
write!(
f,
[
l_angle_token.format(),
name.format(),
space(),
attributes.format(),
space(),
]
)?;
[&group(&format_with(|f| {
attributes.format().fmt(f)?;

// Whitespace sensitivity takes precedence over bracketSameLine for correctness.
//
// The r_angle is placed inside this group because prettier always includes this token
// in the same group as the attributes, unless the token is being borrowed.
// When these tokens are borrowed, they are managed by the sibling `HtmlElementList` formatter.
if bracket_same_line {
write!(f, [hard_space()])?;
} else {
write!(f, [soft_line_break_or_space()])?;
}

if slash_token.is_some() {
write!(f, [slash_token.format()])?;
} else {
write!(f, [text("/")])?;
}
// TODO: These tokens (the `/>`) are not yet borrowed by sibling elements for whitespace sensitivity.
// To resolve this, these tokens either need to be passed to or deferred to sibling text elements when
// whitespace sensitivity would require it.
if slash_token.is_some() {
write!(f, [slash_token.format()])?;
} else {
write!(f, [text("/")])?;
}

write!(f, [r_angle_token.format()])?;
Ok(())
}))
.with_group_id(Some(attr_group_id))]
)?;

write!(f, [r_angle_token.format()])
Ok(())
}
}
32 changes: 21 additions & 11 deletions crates/biome_html_formatter/src/html/lists/attribute_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,32 @@ pub(crate) struct FormatHtmlAttributeList;
impl FormatRule<HtmlAttributeList> for FormatHtmlAttributeList {
type Context = HtmlFormatContext;
fn fmt(&self, node: &HtmlAttributeList, f: &mut HtmlFormatter) -> FormatResult<()> {
let attribute_len = node.iter().len();
let line_break = if f.options().attribute_position() == AttributePosition::Multiline
&& attribute_len > 1
let attribute_count = node.len();
let attribute_seperator = if f.options().attribute_position()
== AttributePosition::Multiline
&& attribute_count > 1
{
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()
})))]
)
if attribute_count > 0 {
write!(
f,
[
space(),
&soft_line_indent_or_space(&format_with(|f| {
f.join_with(&attribute_seperator)
.entries(node.iter().formatted())
.finish()?;

Ok(())
}))
]
)?;
}

Ok(())
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div
id="hello"
class="world really-long-class-name another-really-long-class-name"
style="color: red"
data-foo="bar"
data-bar="foo"
>
hello world
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
source: crates/biome_formatter_test/src/snapshot_builder.rs
info: elements/bracket-same-line/element.html
---
# Input

```html
<div
id="hello"
class="world really-long-class-name another-really-long-class-name"
style="color: red"
data-foo="bar"
data-bar="foo"
>
hello world
</div>
```


=============================

# Outputs

## Output 1

-----
Indent style: Tab
Indent width: 2
Line ending: LF
Line width: 80
Attribute Position: Auto
Bracket same line: false
Whitespace sensitivity: strict
Indent script and style: false
-----

```html
<div
id="hello"
class="world really-long-class-name another-really-long-class-name"
style="color: red"
data-foo="bar"
data-bar="foo"
>hello world</div>
```

## Output 1

-----
Indent style: Tab
Indent width: 2
Line ending: LF
Line width: 80
Attribute Position: Auto
Bracket same line: true
Whitespace sensitivity: strict
Indent script and style: false
-----

```html
<div
id="hello"
class="world really-long-class-name another-really-long-class-name"
style="color: red"
data-foo="bar"
data-bar="foo">hello world</div>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"$schema": "../../../../../../../../packages/@biomejs/biome/configuration_schema.json",
"formatter": {
"bracketSameLine": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<selfclosing
id="hello"
class="world"
style="color: red"
data-foo="bar"
data-bar="foo"
/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
source: crates/biome_formatter_test/src/snapshot_builder.rs
info: elements/bracket-same-line/self-closing.html
---
# Input

```html
<selfclosing
id="hello"
class="world"
style="color: red"
data-foo="bar"
data-bar="foo"
/>
```


=============================

# Outputs

## Output 1

-----
Indent style: Tab
Indent width: 2
Line ending: LF
Line width: 80
Attribute Position: Auto
Bracket same line: false
Whitespace sensitivity: strict
Indent script and style: false
-----

```html
<selfclosing
id="hello"
class="world"
style="color: red"
data-foo="bar"
data-bar="foo"
/>
```

## Output 1

-----
Indent style: Tab
Indent width: 2
Line ending: LF
Line width: 80
Attribute Position: Auto
Bracket same line: true
Whitespace sensitivity: strict
Indent script and style: false
-----

```html
<selfclosing
id="hello"
class="world"
style="color: red"
data-foo="bar"
data-bar="foo" />
```

0 comments on commit 93dda40

Please sign in to comment.