Rich Harris 3 months ago
parent 1ca1be5a03
commit 80370e3a26

@ -1,5 +1,5 @@
/** @import { AST } from '#compiler'; */
/** @import { Visitors } from 'esrap' */
/** @import { Context, Visitors } from 'esrap' */
import * as esrap from 'esrap';
import ts from 'esrap/languages/ts';
import { is_void } from '../../utils.js';
@ -65,20 +65,71 @@ const visitors = {
},
Fragment(node, context) {
for (let i = 0; i < node.nodes.length; i += 1) {
const child = node.nodes[i];
const join = context.new();
/** @type {Context[]} */
const contexts = [];
if (child.type === 'Text') {
let data = child.data;
let sequence = context.new();
if (i === 0) data = data.trimStart();
if (i === node.nodes.length - 1) data = data.trimEnd();
let multiline = false;
context.write(data);
function flush() {
if (sequence.empty()) {
return;
}
contexts.push(sequence);
sequence = context.new();
}
for (let i = 0; i < node.nodes.length; i += 1) {
const child_node = node.nodes[i];
const prev = node.nodes[i - 1];
const next = node.nodes[i + 1];
const prev_is_text = prev && (prev.type === 'Text' || prev.type === 'ExpressionTag');
const next_is_text = next && (next.type === 'Text' || next.type === 'ExpressionTag');
if (child_node.type === 'Text' || child_node.type === 'ExpressionTag') {
if (child_node.type === 'Text') {
let { data } = child_node;
let a = !prev_is_text && data !== (data = data.trimStart());
let b = !next_is_text && data !== (data = data.trimEnd());
if (data === '') {
if (prev && next) sequence.append(join);
} else {
if (a && prev) sequence.append(join);
sequence.write(data);
if (b && next) sequence.append(join);
}
} else {
sequence.visit(child_node);
}
} else {
context.visit(child);
flush();
const child_context = context.new();
child_context.visit(child_node);
contexts.push(child_context);
multiline ||= child_context.multiline;
}
}
flush();
if (multiline) {
join.newline();
} else {
join.write(' ');
}
for (const child_context of contexts) {
context.append(child_context);
}
},
AnimateDirective(node, context) {
@ -329,14 +380,24 @@ const visitors = {
context.write('{:else if ');
context.visit(node.test);
context.write('}');
context.indent();
context.newline();
context.visit(node.consequent);
context.dedent();
context.newline();
} else {
context.write('{#if ');
context.visit(node.test);
context.write('}');
context.indent();
context.newline();
context.visit(node.consequent);
context.dedent();
context.newline();
}
if (node.alternate !== null) {
if (
!(
@ -347,8 +408,14 @@ const visitors = {
) {
context.write('{:else}');
}
context.indent();
context.newline();
context.visit(node.alternate);
context.dedent();
context.newline();
}
if (!node.elseif) {
context.write('{/if}');
}

@ -0,0 +1 @@
{#if condition} yes {:else} no {/if}

@ -0,0 +1,5 @@
{#if condition}
yes
{:else}
no
{/if}

@ -23,7 +23,7 @@ const { test, run } = suite<ParserTest>(async (config, cwd) => {
const file = `${cwd}/output.svelte`;
const expected = fs.existsSync(file) ? fs.readFileSync(file, 'utf-8') : '';
assert.deepEqual(output.code, expected);
assert.deepEqual(output.code.trim(), expected.trim());
}
});

Loading…
Cancel
Save