11/** @import { AST } from '#compiler'; */
2- /** @import { Visitors } from 'esrap' */
2+ /** @import { Context, Visitors } from 'esrap' */
33import * as esrap from 'esrap' ;
44import ts from 'esrap/languages/ts' ;
55import { is_void } from '../../utils.js' ;
@@ -65,20 +65,71 @@ const visitors = {
6565 } ,
6666
6767 Fragment ( node , context ) {
68- for ( let i = 0 ; i < node . nodes . length ; i += 1 ) {
69- const child = node . nodes [ i ] ;
68+ const join = context . new ( ) ;
69+
70+ /** @type {Context[] } */
71+ const contexts = [ ] ;
7072
71- if ( child . type === 'Text' ) {
72- let data = child . data ;
73+ let sequence = context . new ( ) ;
7374
74- if ( i === 0 ) data = data . trimStart ( ) ;
75- if ( i === node . nodes . length - 1 ) data = data . trimEnd ( ) ;
75+ let multiline = false ;
7676
77- context . write ( data ) ;
77+ function flush ( ) {
78+ if ( sequence . empty ( ) ) {
79+ return ;
80+ }
81+
82+ contexts . push ( sequence ) ;
83+ sequence = context . new ( ) ;
84+ }
85+
86+ for ( let i = 0 ; i < node . nodes . length ; i += 1 ) {
87+ const child_node = node . nodes [ i ] ;
88+ const prev = node . nodes [ i - 1 ] ;
89+ const next = node . nodes [ i + 1 ] ;
90+
91+ const prev_is_text = prev && ( prev . type === 'Text' || prev . type === 'ExpressionTag' ) ;
92+ const next_is_text = next && ( next . type === 'Text' || next . type === 'ExpressionTag' ) ;
93+
94+ if ( child_node . type === 'Text' || child_node . type === 'ExpressionTag' ) {
95+ if ( child_node . type === 'Text' ) {
96+ let { data } = child_node ;
97+
98+ let a = ! prev_is_text && data !== ( data = data . trimStart ( ) ) ;
99+ let b = ! next_is_text && data !== ( data = data . trimEnd ( ) ) ;
100+
101+ if ( data === '' ) {
102+ if ( prev && next ) sequence . append ( join ) ;
103+ } else {
104+ if ( a && prev ) sequence . append ( join ) ;
105+ sequence . write ( data ) ;
106+ if ( b && next ) sequence . append ( join ) ;
107+ }
108+ } else {
109+ sequence . visit ( child_node ) ;
110+ }
78111 } else {
79- context . visit ( child ) ;
112+ flush ( ) ;
113+ const child_context = context . new ( ) ;
114+ child_context . visit ( child_node ) ;
115+
116+ contexts . push ( child_context ) ;
117+
118+ multiline ||= child_context . multiline ;
80119 }
81120 }
121+
122+ flush ( ) ;
123+
124+ if ( multiline ) {
125+ join . newline ( ) ;
126+ } else {
127+ join . write ( ' ' ) ;
128+ }
129+
130+ for ( const child_context of contexts ) {
131+ context . append ( child_context ) ;
132+ }
82133 } ,
83134
84135 AnimateDirective ( node , context ) {
@@ -329,14 +380,24 @@ const visitors = {
329380 context . write ( '{:else if ' ) ;
330381 context . visit ( node . test ) ;
331382 context . write ( '}' ) ;
383+
384+ context . indent ( ) ;
385+ context . newline ( ) ;
332386 context . visit ( node . consequent ) ;
387+ context . dedent ( ) ;
388+ context . newline ( ) ;
333389 } else {
334390 context . write ( '{#if ' ) ;
335391 context . visit ( node . test ) ;
336392 context . write ( '}' ) ;
337393
394+ context . indent ( ) ;
395+ context . newline ( ) ;
338396 context . visit ( node . consequent ) ;
397+ context . dedent ( ) ;
398+ context . newline ( ) ;
339399 }
400+
340401 if ( node . alternate !== null ) {
341402 if (
342403 ! (
@@ -347,8 +408,14 @@ const visitors = {
347408 ) {
348409 context . write ( '{:else}' ) ;
349410 }
411+
412+ context . indent ( ) ;
413+ context . newline ( ) ;
350414 context . visit ( node . alternate ) ;
415+ context . dedent ( ) ;
416+ context . newline ( ) ;
351417 }
418+
352419 if ( ! node . elseif ) {
353420 context . write ( '{/if}' ) ;
354421 }
0 commit comments