@@ -44,7 +44,8 @@ use biome_html_syntax::{
4444 AnySvelteDirective , AstroEmbeddedContent , HtmlAttributeInitializerClause ,
4545 HtmlDoubleTextExpression , HtmlElement , HtmlFileSource , HtmlLanguage , HtmlRoot ,
4646 HtmlSingleTextExpression , HtmlSyntaxNode , HtmlTextExpression , HtmlTextExpressions , HtmlVariant ,
47- VueDirective , VueVBindShorthandDirective , VueVOnShorthandDirective , VueVSlotShorthandDirective ,
47+ SvelteAwaitBlock , SvelteEachBlock , SvelteIfBlock , SvelteKeyBlock , VueDirective ,
48+ VueVBindShorthandDirective , VueVOnShorthandDirective , VueVSlotShorthandDirective ,
4849} ;
4950use biome_js_parser:: parse_js_with_offset_and_cache;
5051use biome_js_syntax:: { EmbeddingKind , JsFileSource , JsLanguage } ;
@@ -763,6 +764,91 @@ fn parse_embedded_nodes(
763764 }
764765 }
765766
767+ // Parse Svelte control flow block expressions ({#if}, {#each}, {#await}, {#key})
768+ for element in html_root. syntax ( ) . descendants ( ) {
769+ let file_source = embedded_file_source
770+ . with_embedding_kind ( EmbeddingKind :: Svelte { is_source : false } ) ;
771+
772+ // Handle {#if expression}
773+ if let Some ( if_block) = SvelteIfBlock :: cast_ref ( & element)
774+ && let Ok ( opening_block) = if_block. opening_block ( )
775+ && let Ok ( expression) = opening_block. expression ( )
776+ && let Some ( ( content, doc_source) ) =
777+ parse_text_expression ( expression, cache, biome_path, settings, file_source)
778+ {
779+ nodes. push ( ( content. into ( ) , doc_source) ) ;
780+ }
781+
782+ // Handle {:else if expression}
783+ if let Some ( if_block) = SvelteIfBlock :: cast_ref ( & element) {
784+ for else_if_clause in if_block. else_if_clauses ( ) {
785+ if let Ok ( expression) = else_if_clause. expression ( )
786+ && let Some ( ( content, doc_source) ) = parse_text_expression (
787+ expression,
788+ cache,
789+ biome_path,
790+ settings,
791+ file_source,
792+ )
793+ {
794+ nodes. push ( ( content. into ( ) , doc_source) ) ;
795+ }
796+ }
797+ }
798+
799+ // Handle {#each expression as item}
800+ if let Some ( each_block) = SvelteEachBlock :: cast_ref ( & element)
801+ && let Ok ( opening_block) = each_block. opening_block ( )
802+ {
803+ if let Ok ( expression) = opening_block. list ( )
804+ && let Some ( ( content, doc_source) ) = parse_text_expression (
805+ expression,
806+ cache,
807+ biome_path,
808+ settings,
809+ file_source,
810+ )
811+ {
812+ nodes. push ( ( content. into ( ) , doc_source) ) ;
813+ }
814+
815+ if let Some ( item) = opening_block. item ( )
816+ && let Some ( item) = item. as_svelte_each_as_keyed_item ( )
817+ && let Some ( key) = item. key ( )
818+ && let Ok ( key_expression) = key. expression ( )
819+ && let Some ( ( content, doc_source) ) = parse_text_expression (
820+ key_expression,
821+ cache,
822+ biome_path,
823+ settings,
824+ file_source,
825+ )
826+ {
827+ nodes. push ( ( content. into ( ) , doc_source) ) ;
828+ }
829+ }
830+
831+ // Handle {#await expression}
832+ if let Some ( await_block) = SvelteAwaitBlock :: cast_ref ( & element)
833+ && let Ok ( opening_block) = await_block. opening_block ( )
834+ && let Ok ( expression) = opening_block. expression ( )
835+ && let Some ( ( content, doc_source) ) =
836+ parse_text_expression ( expression, cache, biome_path, settings, file_source)
837+ {
838+ nodes. push ( ( content. into ( ) , doc_source) ) ;
839+ }
840+
841+ // Handle {#key expression}
842+ if let Some ( key_block) = SvelteKeyBlock :: cast_ref ( & element)
843+ && let Ok ( opening_block) = key_block. opening_block ( )
844+ && let Ok ( expression) = opening_block. expression ( )
845+ && let Some ( ( content, doc_source) ) =
846+ parse_text_expression ( expression, cache, biome_path, settings, file_source)
847+ {
848+ nodes. push ( ( content. into ( ) , doc_source) ) ;
849+ }
850+ }
851+
766852 // Parse Svelte directive attributes (bind:, class:, use:, etc.)
767853 // Note: on: event handlers are legacy Svelte 3/4 syntax and not supported.
768854 // Svelte 5 runes mode uses regular attributes for event handlers.
0 commit comments