diff --git a/.changeset/fix-html-dashes-in-element-content.md b/.changeset/fix-html-dashes-in-element-content.md new file mode 100644 index 000000000000..b22ae1bbb9e7 --- /dev/null +++ b/.changeset/fix-html-dashes-in-element-content.md @@ -0,0 +1,5 @@ +--- +"@biomejs/biome": patch +--- + +Fixed [#9238](https://github.com/biomejs/biome/issues/9238): The HTML parser no longer incorrectly reports `---` inside element content (e.g. `---`) as an "Unexpected value or character" error. diff --git a/crates/biome_html_parser/src/syntax/mod.rs b/crates/biome_html_parser/src/syntax/mod.rs index 7e69f2c42656..94fce7549b03 100644 --- a/crates/biome_html_parser/src/syntax/mod.rs +++ b/crates/biome_html_parser/src/syntax/mod.rs @@ -98,9 +98,7 @@ pub(crate) fn parse_root(p: &mut HtmlParser) { // Whether or not frontmatter was present, once we're past the frontmatter // position `---` can no longer start a fence. This prevents `---` in HTML // content from being incorrectly lexed as a FENCE token. - if p.options().frontmatter { - p.set_after_frontmatter(true); - } + p.set_after_frontmatter(true); parse_doc_type(p).ok(); ElementList.parse_list(p); diff --git a/crates/biome_html_parser/tests/html_specs/ok/dashes_in_element_content.html b/crates/biome_html_parser/tests/html_specs/ok/dashes_in_element_content.html new file mode 100644 index 000000000000..09fc76afd9c7 --- /dev/null +++ b/crates/biome_html_parser/tests/html_specs/ok/dashes_in_element_content.html @@ -0,0 +1,14 @@ + + + + + + + + + + +
NameDescription
---create a duration of 0ms
+
---
+

-- text --

+--- some text --- diff --git a/crates/biome_html_parser/tests/html_specs/ok/dashes_in_element_content.html.snap b/crates/biome_html_parser/tests/html_specs/ok/dashes_in_element_content.html.snap new file mode 100644 index 000000000000..04412629f06a --- /dev/null +++ b/crates/biome_html_parser/tests/html_specs/ok/dashes_in_element_content.html.snap @@ -0,0 +1,493 @@ +--- +source: crates/biome_html_parser/tests/spec_test.rs +expression: snapshot +--- + +## Input + +```html + + + + + + + + + + +
NameDescription
---create a duration of 0ms
+
---
+

-- text --

+--- some text --- + +``` + + +## 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..6 "table" [] [], + }, + attributes: HtmlAttributeList [], + r_angle_token: R_ANGLE@6..7 ">" [] [], + }, + children: HtmlElementList [ + HtmlElement { + opening_element: HtmlOpeningElement { + l_angle_token: L_ANGLE@7..9 "<" [Newline("\n")] [], + name: HtmlTagName { + value_token: HTML_LITERAL@9..14 "thead" [] [], + }, + attributes: HtmlAttributeList [], + r_angle_token: R_ANGLE@14..15 ">" [] [], + }, + children: HtmlElementList [ + HtmlElement { + opening_element: HtmlOpeningElement { + l_angle_token: L_ANGLE@15..17 "<" [Newline("\n")] [], + name: HtmlTagName { + value_token: HTML_LITERAL@17..19 "tr" [] [], + }, + attributes: HtmlAttributeList [], + r_angle_token: R_ANGLE@19..20 ">" [] [], + }, + children: HtmlElementList [ + HtmlElement { + opening_element: HtmlOpeningElement { + l_angle_token: L_ANGLE@20..21 "<" [] [], + name: HtmlTagName { + value_token: HTML_LITERAL@21..23 "th" [] [], + }, + attributes: HtmlAttributeList [], + r_angle_token: R_ANGLE@23..24 ">" [] [], + }, + children: HtmlElementList [ + HtmlContent { + value_token: HTML_LITERAL@24..28 "Name" [] [], + }, + ], + closing_element: HtmlClosingElement { + l_angle_token: L_ANGLE@28..29 "<" [] [], + slash_token: SLASH@29..30 "/" [] [], + name: HtmlTagName { + value_token: HTML_LITERAL@30..32 "th" [] [], + }, + r_angle_token: R_ANGLE@32..33 ">" [] [], + }, + }, + HtmlElement { + opening_element: HtmlOpeningElement { + l_angle_token: L_ANGLE@33..34 "<" [] [], + name: HtmlTagName { + value_token: HTML_LITERAL@34..36 "th" [] [], + }, + attributes: HtmlAttributeList [], + r_angle_token: R_ANGLE@36..37 ">" [] [], + }, + children: HtmlElementList [ + HtmlContent { + value_token: HTML_LITERAL@37..48 "Description" [] [], + }, + ], + closing_element: HtmlClosingElement { + l_angle_token: L_ANGLE@48..49 "<" [] [], + slash_token: SLASH@49..50 "/" [] [], + name: HtmlTagName { + value_token: HTML_LITERAL@50..52 "th" [] [], + }, + r_angle_token: R_ANGLE@52..53 ">" [] [], + }, + }, + ], + closing_element: HtmlClosingElement { + l_angle_token: L_ANGLE@53..54 "<" [] [], + slash_token: SLASH@54..55 "/" [] [], + name: HtmlTagName { + value_token: HTML_LITERAL@55..57 "tr" [] [], + }, + r_angle_token: R_ANGLE@57..58 ">" [] [], + }, + }, + ], + closing_element: HtmlClosingElement { + l_angle_token: L_ANGLE@58..60 "<" [Newline("\n")] [], + slash_token: SLASH@60..61 "/" [] [], + name: HtmlTagName { + value_token: HTML_LITERAL@61..66 "thead" [] [], + }, + r_angle_token: R_ANGLE@66..67 ">" [] [], + }, + }, + HtmlElement { + opening_element: HtmlOpeningElement { + l_angle_token: L_ANGLE@67..69 "<" [Newline("\n")] [], + name: HtmlTagName { + value_token: HTML_LITERAL@69..74 "tbody" [] [], + }, + attributes: HtmlAttributeList [], + r_angle_token: R_ANGLE@74..75 ">" [] [], + }, + children: HtmlElementList [ + HtmlElement { + opening_element: HtmlOpeningElement { + l_angle_token: L_ANGLE@75..77 "<" [Newline("\n")] [], + name: HtmlTagName { + value_token: HTML_LITERAL@77..79 "tr" [] [], + }, + attributes: HtmlAttributeList [], + r_angle_token: R_ANGLE@79..80 ">" [] [], + }, + children: HtmlElementList [ + HtmlElement { + opening_element: HtmlOpeningElement { + l_angle_token: L_ANGLE@80..82 "<" [Newline("\n")] [], + name: HtmlTagName { + value_token: HTML_LITERAL@82..84 "td" [] [], + }, + attributes: HtmlAttributeList [], + r_angle_token: R_ANGLE@84..85 ">" [] [], + }, + children: HtmlElementList [ + HtmlContent { + value_token: HTML_LITERAL@85..88 "---" [] [], + }, + ], + closing_element: HtmlClosingElement { + l_angle_token: L_ANGLE@88..89 "<" [] [], + slash_token: SLASH@89..90 "/" [] [], + name: HtmlTagName { + value_token: HTML_LITERAL@90..92 "td" [] [], + }, + r_angle_token: R_ANGLE@92..93 ">" [] [], + }, + }, + HtmlElement { + opening_element: HtmlOpeningElement { + l_angle_token: L_ANGLE@93..95 "<" [Newline("\n")] [], + name: HtmlTagName { + value_token: HTML_LITERAL@95..97 "td" [] [], + }, + attributes: HtmlAttributeList [], + r_angle_token: R_ANGLE@97..98 ">" [] [], + }, + children: HtmlElementList [ + HtmlContent { + value_token: HTML_LITERAL@98..122 "create a duration of 0ms" [] [], + }, + ], + closing_element: HtmlClosingElement { + l_angle_token: L_ANGLE@122..123 "<" [] [], + slash_token: SLASH@123..124 "/" [] [], + name: HtmlTagName { + value_token: HTML_LITERAL@124..126 "td" [] [], + }, + r_angle_token: R_ANGLE@126..127 ">" [] [], + }, + }, + ], + closing_element: HtmlClosingElement { + l_angle_token: L_ANGLE@127..129 "<" [Newline("\n")] [], + slash_token: SLASH@129..130 "/" [] [], + name: HtmlTagName { + value_token: HTML_LITERAL@130..132 "tr" [] [], + }, + r_angle_token: R_ANGLE@132..133 ">" [] [], + }, + }, + ], + closing_element: HtmlClosingElement { + l_angle_token: L_ANGLE@133..135 "<" [Newline("\n")] [], + slash_token: SLASH@135..136 "/" [] [], + name: HtmlTagName { + value_token: HTML_LITERAL@136..141 "tbody" [] [], + }, + r_angle_token: R_ANGLE@141..142 ">" [] [], + }, + }, + ], + closing_element: HtmlClosingElement { + l_angle_token: L_ANGLE@142..144 "<" [Newline("\n")] [], + slash_token: SLASH@144..145 "/" [] [], + name: HtmlTagName { + value_token: HTML_LITERAL@145..150 "table" [] [], + }, + r_angle_token: R_ANGLE@150..151 ">" [] [], + }, + }, + HtmlElement { + opening_element: HtmlOpeningElement { + l_angle_token: L_ANGLE@151..153 "<" [Newline("\n")] [], + name: HtmlTagName { + value_token: HTML_LITERAL@153..156 "div" [] [], + }, + attributes: HtmlAttributeList [], + r_angle_token: R_ANGLE@156..157 ">" [] [], + }, + children: HtmlElementList [ + HtmlContent { + value_token: HTML_LITERAL@157..160 "---" [] [], + }, + ], + closing_element: HtmlClosingElement { + l_angle_token: L_ANGLE@160..161 "<" [] [], + slash_token: SLASH@161..162 "/" [] [], + name: HtmlTagName { + value_token: HTML_LITERAL@162..165 "div" [] [], + }, + r_angle_token: R_ANGLE@165..166 ">" [] [], + }, + }, + HtmlElement { + opening_element: HtmlOpeningElement { + l_angle_token: L_ANGLE@166..168 "<" [Newline("\n")] [], + name: HtmlTagName { + value_token: HTML_LITERAL@168..169 "p" [] [], + }, + attributes: HtmlAttributeList [], + r_angle_token: R_ANGLE@169..170 ">" [] [], + }, + children: HtmlElementList [ + HtmlContent { + value_token: HTML_LITERAL@170..180 "-- text --" [] [], + }, + ], + closing_element: HtmlClosingElement { + l_angle_token: L_ANGLE@180..181 "<" [] [], + slash_token: SLASH@181..182 "/" [] [], + name: HtmlTagName { + value_token: HTML_LITERAL@182..183 "p" [] [], + }, + r_angle_token: R_ANGLE@183..184 ">" [] [], + }, + }, + HtmlElement { + opening_element: HtmlOpeningElement { + l_angle_token: L_ANGLE@184..186 "<" [Newline("\n")] [], + name: HtmlTagName { + value_token: HTML_LITERAL@186..190 "span" [] [], + }, + attributes: HtmlAttributeList [], + r_angle_token: R_ANGLE@190..191 ">" [] [], + }, + children: HtmlElementList [ + HtmlContent { + value_token: HTML_LITERAL@191..208 "--- some text ---" [] [], + }, + ], + closing_element: HtmlClosingElement { + l_angle_token: L_ANGLE@208..209 "<" [] [], + slash_token: SLASH@209..210 "/" [] [], + name: HtmlTagName { + value_token: HTML_LITERAL@210..214 "span" [] [], + }, + r_angle_token: R_ANGLE@214..215 ">" [] [], + }, + }, + ], + eof_token: EOF@215..216 "" [Newline("\n")] [], +} +``` + +## CST + +``` +0: HTML_ROOT@0..216 + 0: (empty) + 1: (empty) + 2: (empty) + 3: HTML_ELEMENT_LIST@0..215 + 0: HTML_ELEMENT@0..151 + 0: HTML_OPENING_ELEMENT@0..7 + 0: L_ANGLE@0..1 "<" [] [] + 1: HTML_TAG_NAME@1..6 + 0: HTML_LITERAL@1..6 "table" [] [] + 2: HTML_ATTRIBUTE_LIST@6..6 + 3: R_ANGLE@6..7 ">" [] [] + 1: HTML_ELEMENT_LIST@7..142 + 0: HTML_ELEMENT@7..67 + 0: HTML_OPENING_ELEMENT@7..15 + 0: L_ANGLE@7..9 "<" [Newline("\n")] [] + 1: HTML_TAG_NAME@9..14 + 0: HTML_LITERAL@9..14 "thead" [] [] + 2: HTML_ATTRIBUTE_LIST@14..14 + 3: R_ANGLE@14..15 ">" [] [] + 1: HTML_ELEMENT_LIST@15..58 + 0: HTML_ELEMENT@15..58 + 0: HTML_OPENING_ELEMENT@15..20 + 0: L_ANGLE@15..17 "<" [Newline("\n")] [] + 1: HTML_TAG_NAME@17..19 + 0: HTML_LITERAL@17..19 "tr" [] [] + 2: HTML_ATTRIBUTE_LIST@19..19 + 3: R_ANGLE@19..20 ">" [] [] + 1: HTML_ELEMENT_LIST@20..53 + 0: HTML_ELEMENT@20..33 + 0: HTML_OPENING_ELEMENT@20..24 + 0: L_ANGLE@20..21 "<" [] [] + 1: HTML_TAG_NAME@21..23 + 0: HTML_LITERAL@21..23 "th" [] [] + 2: HTML_ATTRIBUTE_LIST@23..23 + 3: R_ANGLE@23..24 ">" [] [] + 1: HTML_ELEMENT_LIST@24..28 + 0: HTML_CONTENT@24..28 + 0: HTML_LITERAL@24..28 "Name" [] [] + 2: HTML_CLOSING_ELEMENT@28..33 + 0: L_ANGLE@28..29 "<" [] [] + 1: SLASH@29..30 "/" [] [] + 2: HTML_TAG_NAME@30..32 + 0: HTML_LITERAL@30..32 "th" [] [] + 3: R_ANGLE@32..33 ">" [] [] + 1: HTML_ELEMENT@33..53 + 0: HTML_OPENING_ELEMENT@33..37 + 0: L_ANGLE@33..34 "<" [] [] + 1: HTML_TAG_NAME@34..36 + 0: HTML_LITERAL@34..36 "th" [] [] + 2: HTML_ATTRIBUTE_LIST@36..36 + 3: R_ANGLE@36..37 ">" [] [] + 1: HTML_ELEMENT_LIST@37..48 + 0: HTML_CONTENT@37..48 + 0: HTML_LITERAL@37..48 "Description" [] [] + 2: HTML_CLOSING_ELEMENT@48..53 + 0: L_ANGLE@48..49 "<" [] [] + 1: SLASH@49..50 "/" [] [] + 2: HTML_TAG_NAME@50..52 + 0: HTML_LITERAL@50..52 "th" [] [] + 3: R_ANGLE@52..53 ">" [] [] + 2: HTML_CLOSING_ELEMENT@53..58 + 0: L_ANGLE@53..54 "<" [] [] + 1: SLASH@54..55 "/" [] [] + 2: HTML_TAG_NAME@55..57 + 0: HTML_LITERAL@55..57 "tr" [] [] + 3: R_ANGLE@57..58 ">" [] [] + 2: HTML_CLOSING_ELEMENT@58..67 + 0: L_ANGLE@58..60 "<" [Newline("\n")] [] + 1: SLASH@60..61 "/" [] [] + 2: HTML_TAG_NAME@61..66 + 0: HTML_LITERAL@61..66 "thead" [] [] + 3: R_ANGLE@66..67 ">" [] [] + 1: HTML_ELEMENT@67..142 + 0: HTML_OPENING_ELEMENT@67..75 + 0: L_ANGLE@67..69 "<" [Newline("\n")] [] + 1: HTML_TAG_NAME@69..74 + 0: HTML_LITERAL@69..74 "tbody" [] [] + 2: HTML_ATTRIBUTE_LIST@74..74 + 3: R_ANGLE@74..75 ">" [] [] + 1: HTML_ELEMENT_LIST@75..133 + 0: HTML_ELEMENT@75..133 + 0: HTML_OPENING_ELEMENT@75..80 + 0: L_ANGLE@75..77 "<" [Newline("\n")] [] + 1: HTML_TAG_NAME@77..79 + 0: HTML_LITERAL@77..79 "tr" [] [] + 2: HTML_ATTRIBUTE_LIST@79..79 + 3: R_ANGLE@79..80 ">" [] [] + 1: HTML_ELEMENT_LIST@80..127 + 0: HTML_ELEMENT@80..93 + 0: HTML_OPENING_ELEMENT@80..85 + 0: L_ANGLE@80..82 "<" [Newline("\n")] [] + 1: HTML_TAG_NAME@82..84 + 0: HTML_LITERAL@82..84 "td" [] [] + 2: HTML_ATTRIBUTE_LIST@84..84 + 3: R_ANGLE@84..85 ">" [] [] + 1: HTML_ELEMENT_LIST@85..88 + 0: HTML_CONTENT@85..88 + 0: HTML_LITERAL@85..88 "---" [] [] + 2: HTML_CLOSING_ELEMENT@88..93 + 0: L_ANGLE@88..89 "<" [] [] + 1: SLASH@89..90 "/" [] [] + 2: HTML_TAG_NAME@90..92 + 0: HTML_LITERAL@90..92 "td" [] [] + 3: R_ANGLE@92..93 ">" [] [] + 1: HTML_ELEMENT@93..127 + 0: HTML_OPENING_ELEMENT@93..98 + 0: L_ANGLE@93..95 "<" [Newline("\n")] [] + 1: HTML_TAG_NAME@95..97 + 0: HTML_LITERAL@95..97 "td" [] [] + 2: HTML_ATTRIBUTE_LIST@97..97 + 3: R_ANGLE@97..98 ">" [] [] + 1: HTML_ELEMENT_LIST@98..122 + 0: HTML_CONTENT@98..122 + 0: HTML_LITERAL@98..122 "create a duration of 0ms" [] [] + 2: HTML_CLOSING_ELEMENT@122..127 + 0: L_ANGLE@122..123 "<" [] [] + 1: SLASH@123..124 "/" [] [] + 2: HTML_TAG_NAME@124..126 + 0: HTML_LITERAL@124..126 "td" [] [] + 3: R_ANGLE@126..127 ">" [] [] + 2: HTML_CLOSING_ELEMENT@127..133 + 0: L_ANGLE@127..129 "<" [Newline("\n")] [] + 1: SLASH@129..130 "/" [] [] + 2: HTML_TAG_NAME@130..132 + 0: HTML_LITERAL@130..132 "tr" [] [] + 3: R_ANGLE@132..133 ">" [] [] + 2: HTML_CLOSING_ELEMENT@133..142 + 0: L_ANGLE@133..135 "<" [Newline("\n")] [] + 1: SLASH@135..136 "/" [] [] + 2: HTML_TAG_NAME@136..141 + 0: HTML_LITERAL@136..141 "tbody" [] [] + 3: R_ANGLE@141..142 ">" [] [] + 2: HTML_CLOSING_ELEMENT@142..151 + 0: L_ANGLE@142..144 "<" [Newline("\n")] [] + 1: SLASH@144..145 "/" [] [] + 2: HTML_TAG_NAME@145..150 + 0: HTML_LITERAL@145..150 "table" [] [] + 3: R_ANGLE@150..151 ">" [] [] + 1: HTML_ELEMENT@151..166 + 0: HTML_OPENING_ELEMENT@151..157 + 0: L_ANGLE@151..153 "<" [Newline("\n")] [] + 1: HTML_TAG_NAME@153..156 + 0: HTML_LITERAL@153..156 "div" [] [] + 2: HTML_ATTRIBUTE_LIST@156..156 + 3: R_ANGLE@156..157 ">" [] [] + 1: HTML_ELEMENT_LIST@157..160 + 0: HTML_CONTENT@157..160 + 0: HTML_LITERAL@157..160 "---" [] [] + 2: HTML_CLOSING_ELEMENT@160..166 + 0: L_ANGLE@160..161 "<" [] [] + 1: SLASH@161..162 "/" [] [] + 2: HTML_TAG_NAME@162..165 + 0: HTML_LITERAL@162..165 "div" [] [] + 3: R_ANGLE@165..166 ">" [] [] + 2: HTML_ELEMENT@166..184 + 0: HTML_OPENING_ELEMENT@166..170 + 0: L_ANGLE@166..168 "<" [Newline("\n")] [] + 1: HTML_TAG_NAME@168..169 + 0: HTML_LITERAL@168..169 "p" [] [] + 2: HTML_ATTRIBUTE_LIST@169..169 + 3: R_ANGLE@169..170 ">" [] [] + 1: HTML_ELEMENT_LIST@170..180 + 0: HTML_CONTENT@170..180 + 0: HTML_LITERAL@170..180 "-- text --" [] [] + 2: HTML_CLOSING_ELEMENT@180..184 + 0: L_ANGLE@180..181 "<" [] [] + 1: SLASH@181..182 "/" [] [] + 2: HTML_TAG_NAME@182..183 + 0: HTML_LITERAL@182..183 "p" [] [] + 3: R_ANGLE@183..184 ">" [] [] + 3: HTML_ELEMENT@184..215 + 0: HTML_OPENING_ELEMENT@184..191 + 0: L_ANGLE@184..186 "<" [Newline("\n")] [] + 1: HTML_TAG_NAME@186..190 + 0: HTML_LITERAL@186..190 "span" [] [] + 2: HTML_ATTRIBUTE_LIST@190..190 + 3: R_ANGLE@190..191 ">" [] [] + 1: HTML_ELEMENT_LIST@191..208 + 0: HTML_CONTENT@191..208 + 0: HTML_LITERAL@191..208 "--- some text ---" [] [] + 2: HTML_CLOSING_ELEMENT@208..215 + 0: L_ANGLE@208..209 "<" [] [] + 1: SLASH@209..210 "/" [] [] + 2: HTML_TAG_NAME@210..214 + 0: HTML_LITERAL@210..214 "span" [] [] + 3: R_ANGLE@214..215 ">" [] [] + 4: EOF@215..216 "" [Newline("\n")] [] + +```