Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/odd-lizards-build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@biomejs/biome": patch
---

Fixed [#7861](https://github.com/biomejs/biome/issues/7861): The HTML parser will now accept Svelte attribute shorthand syntax in `.svelte` files.
1 change: 1 addition & 0 deletions crates/biome_html_formatter/src/html/any/attribute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ impl FormatRule<AnyHtmlAttribute> for FormatAnyHtmlAttribute {
AnyHtmlAttribute::HtmlAttribute(node) => node.format().fmt(f),
AnyHtmlAttribute::HtmlBogusAttribute(node) => node.format().fmt(f),
AnyHtmlAttribute::HtmlDoubleTextExpression(node) => node.format().fmt(f),
AnyHtmlAttribute::HtmlSingleTextExpression(node) => node.format().fmt(f),
}
}
}
3 changes: 3 additions & 0 deletions crates/biome_html_formatter/src/html/lists/attribute_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ impl FormatRule<HtmlAttributeList> for FormatHtmlAttributeList {
AnyHtmlAttribute::HtmlDoubleTextExpression(attr) => {
attr.format().fmt(f)
}
AnyHtmlAttribute::HtmlSingleTextExpression(attr) => {
attr.format().fmt(f)
}
AnyHtmlAttribute::HtmlBogusAttribute(attr) => {
attr.format().fmt(f)
}
Expand Down
Empty file.
9 changes: 8 additions & 1 deletion crates/biome_html_parser/src/syntax/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,13 @@ fn parse_attribute(p: &mut HtmlParser) -> ParsedSyntax {
.ok();

Present(m.complete(p, HTML_ATTRIBUTE))
} else if p.at(T!['{']) {
m.abandon(p);
HtmlSyntaxFeatures::SingleTextExpressions.parse_exclusive_syntax(
p,
|p| parse_single_text_expression(p, HtmlLexContext::InsideTag),
|p: &HtmlParser<'_>, m: &CompletedMarker| disabled_svelte_prop(p, m.range(p)),
)
} else {
parse_literal(p, HTML_ATTRIBUTE_NAME).or_add_diagnostic(p, expected_attribute);
if p.at(T![=]) {
Expand All @@ -324,7 +331,7 @@ fn parse_attribute(p: &mut HtmlParser) -> ParsedSyntax {
}

fn is_at_attribute_start(p: &mut HtmlParser) -> bool {
p.at(HTML_LITERAL) || p.at(T!["{{"]) || p.at(T!['{'])
p.at_ts(token_set![HTML_LITERAL, T!["{{"], T!['{']])
}

fn parse_literal(p: &mut HtmlParser, kind: HtmlSyntaxKind) -> ParsedSyntax {
Expand Down
4 changes: 4 additions & 0 deletions crates/biome_html_parser/src/syntax/parse_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ pub(crate) fn disabled_interpolation(p: &HtmlParser, range: TextRange) -> ParseD
p.err_builder("Text expressions aren't supported.", range).with_hint(markup!("Remove it or enable the parsing using the "<Emphasis>"html.parser.interpolation"</Emphasis>" option."))
}

pub(crate) fn disabled_svelte_prop(p: &HtmlParser, range: TextRange) -> ParseDiagnostic {
p.err_builder("This looks like Svelte syntax, but this is not a Svelte file.", range).with_hint(markup!("Remove it or rename this file to have the "<Emphasis>".svelte"</Emphasis>" file extension."))
}

pub(crate) fn expected_text_expression(
p: &HtmlParser,
curr_range: TextRange,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<button {disabled}></button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
---
source: crates/biome_html_parser/tests/spec_test.rs
expression: snapshot
---
## Input

```html
<button {disabled}></button>
```


## AST

```
HtmlRoot {
bom_token: missing (optional),
frontmatter: missing (optional),
directive: missing (optional),
html: HtmlElementList [
HtmlBogusElement {
items: [
HtmlBogus {
items: [
L_ANGLE@0..1 "<" [] [],
HtmlTagName {
value_token: HTML_LITERAL@1..8 "button" [] [Whitespace(" ")],
},
HtmlBogus {
items: [
HtmlBogusElement {
items: [
L_CURLY@8..9 "{" [] [],
HTML_LITERAL@9..19 "disabled}>" [] [],
],
},
],
},
],
},
HtmlElementList [],
HtmlClosingElement {
l_angle_token: L_ANGLE@19..20 "<" [] [],
slash_token: SLASH@20..21 "/" [] [],
name: HtmlTagName {
value_token: HTML_LITERAL@21..27 "button" [] [],
},
r_angle_token: R_ANGLE@27..28 ">" [] [],
},
],
},
],
eof_token: EOF@28..29 "" [Newline("\n")] [],
}
```

## CST

```
0: [email protected]
0: (empty)
1: (empty)
2: (empty)
3: [email protected]
0: [email protected]
0: [email protected]
0: [email protected] "<" [] []
1: [email protected]
0: [email protected] "button" [] [Whitespace(" ")]
2: [email protected]
0: [email protected]
0: [email protected] "{" [] []
1: HTML_LITERAL@9..19 "disabled}>" [] []
1: HTML_ELEMENT_LIST@19..19
2: HTML_CLOSING_ELEMENT@19..28
0: L_ANGLE@19..20 "<" [] []
1: SLASH@20..21 "/" [] []
2: HTML_TAG_NAME@21..27
0: HTML_LITERAL@21..27 "button" [] []
3: R_ANGLE@27..28 ">" [] []
4: EOF@28..29 "" [Newline("\n")] []
```
## Diagnostics
```
interpolation-attributes.html:1:9 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
× Expected an attribute but instead found '{disabled}>'.
> 1<button {disabled}></button>
^^^^^^^^^^^
2
i Expected an attribute here.
> 1<button {disabled}></button>
^^^^^^^^^^^
2
interpolation-attributes.html:1:20 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
× Expected an attribute but instead found '<'.
> 1<button {disabled}></button>
^
2
i Expected an attribute here.
> 1<button {disabled}></button>
^
2
```
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<button disabled={false}>Click me</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
---
source: crates/biome_html_parser/tests/spec_test.rs
expression: snapshot
---
## Input

```svelte
<button disabled={false}>Click me</button>
```


## AST

```
HtmlRoot {
bom_token: missing (optional),
frontmatter: missing (optional),
directive: missing (optional),
html: HtmlElementList [
HtmlElement {
opening_element: HtmlOpeningElement {
l_angle_token: L_ANGLE@0..1 "<" [] [],
name: HtmlTagName {
value_token: HTML_LITERAL@1..8 "button" [] [Whitespace(" ")],
},
attributes: HtmlAttributeList [
HtmlAttribute {
name: HtmlAttributeName {
value_token: HTML_LITERAL@8..16 "disabled" [] [],
},
initializer: HtmlAttributeInitializerClause {
eq_token: EQ@16..17 "=" [] [],
value: HtmlSingleTextExpression {
l_curly_token: L_CURLY@17..18 "{" [] [],
expression: HtmlTextExpression {
html_literal_token: HTML_LITERAL@18..23 "false" [] [],
},
r_curly_token: R_CURLY@23..24 "}" [] [],
},
},
},
],
r_angle_token: R_ANGLE@24..25 ">" [] [],
},
children: HtmlElementList [
HtmlContent {
value_token: HTML_LITERAL@25..33 "Click me" [] [],
},
],
closing_element: HtmlClosingElement {
l_angle_token: L_ANGLE@33..34 "<" [] [],
slash_token: SLASH@34..35 "/" [] [],
name: HtmlTagName {
value_token: HTML_LITERAL@35..41 "button" [] [],
},
r_angle_token: R_ANGLE@41..42 ">" [] [],
},
},
],
eof_token: EOF@42..43 "" [Newline("\n")] [],
}
```

## CST

```
0: [email protected]
0: (empty)
1: (empty)
2: (empty)
3: [email protected]
0: [email protected]
0: [email protected]
0: [email protected] "<" [] []
1: [email protected]
0: [email protected] "button" [] [Whitespace(" ")]
2: [email protected]
0: [email protected]
0: [email protected]
0: [email protected] "disabled" [] []
1: [email protected]
0: [email protected] "=" [] []
1: [email protected]
0: [email protected] "{" [] []
1: HTML_TEXT_EXPRESSION@18..23
0: HTML_LITERAL@18..23 "false" [] []
2: R_CURLY@23..24 "}" [] []
3: R_ANGLE@24..25 ">" [] []
1: HTML_ELEMENT_LIST@25..33
0: HTML_CONTENT@25..33
0: HTML_LITERAL@25..33 "Click me" [] []
2: HTML_CLOSING_ELEMENT@33..42
0: L_ANGLE@33..34 "<" [] []
1: SLASH@34..35 "/" [] []
2: HTML_TAG_NAME@35..41
0: HTML_LITERAL@35..41 "button" [] []
3: R_ANGLE@41..42 ">" [] []
4: EOF@42..43 "" [Newline("\n")] []
```
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<button {disabled}>Click me</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
source: crates/biome_html_parser/tests/spec_test.rs
expression: snapshot
---
## Input

```svelte
<button {disabled}>Click me</button>

```


## AST

```
HtmlRoot {
bom_token: missing (optional),
frontmatter: missing (optional),
directive: missing (optional),
html: HtmlElementList [
HtmlElement {
opening_element: HtmlOpeningElement {
l_angle_token: [email protected] "<" [] [],
name: HtmlTagName {
value_token: [email protected] "button" [] [Whitespace(" ")],
},
attributes: HtmlAttributeList [
HtmlSingleTextExpression {
l_curly_token: [email protected] "{" [] [],
expression: HtmlTextExpression {
html_literal_token: [email protected] "disabled" [] [],
},
r_curly_token: [email protected] "}" [] [],
},
],
r_angle_token: [email protected] ">" [] [],
},
children: HtmlElementList [
HtmlContent {
value_token: [email protected] "Click me" [] [],
},
],
closing_element: HtmlClosingElement {
l_angle_token: [email protected] "<" [] [],
slash_token: [email protected] "/" [] [],
name: HtmlTagName {
value_token: [email protected] "button" [] [],
},
r_angle_token: [email protected] ">" [] [],
},
},
],
eof_token: [email protected] "" [Newline("\n")] [],
}
```

## CST

```
0: [email protected]
0: (empty)
1: (empty)
2: (empty)
3: [email protected]
0: [email protected]
0: [email protected]
0: [email protected] "<" [] []
1: [email protected]
0: [email protected] "button" [] [Whitespace(" ")]
2: [email protected]
0: [email protected]
0: [email protected] "{" [] []
1: [email protected]
0: [email protected] "disabled" [] []
2: [email protected] "}" [] []
3: [email protected] ">" [] []
1: [email protected]
0: [email protected]
0: [email protected] "Click me" [] []
2: [email protected]
0: [email protected] "<" [] []
1: [email protected] "/" [] []
2: [email protected]
0: [email protected] "button" [] []
3: [email protected] ">" [] []
4: [email protected] "" [Newline("\n")] []

```
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<button {...props}>Click me</button>
Loading
Loading