fix: improve template text node serialization (#9722)

fix: improve template text node serialization
pull/9707/head
Dominic Gannaway 1 year ago committed by GitHub
parent 7eba35b9d1
commit 2fa06447cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: improve template text node serialization

@ -1382,13 +1382,17 @@ function process_children(nodes, parent, { visit, state }) {
/**
* @param {Sequence} sequence
* @param {boolean} in_fragment
*/
function flush_sequence(sequence) {
function flush_sequence(sequence, in_fragment) {
if (sequence.length === 1) {
const node = sequence[0];
if (node.type === 'Text') {
if ((in_fragment && node.type === 'ExpressionTag') || node.type === 'Text') {
expression = b.call('$.sibling', expression);
}
if (node.type === 'Text') {
state.template.push(node.raw);
return;
}
@ -1475,7 +1479,7 @@ function process_children(nodes, parent, { visit, state }) {
sequence.push(node);
} else {
if (sequence.length > 0) {
flush_sequence(sequence);
flush_sequence(sequence, true);
sequence = [];
}
@ -1519,7 +1523,7 @@ function process_children(nodes, parent, { visit, state }) {
}
if (sequence.length > 0) {
flush_sequence(sequence);
flush_sequence(sequence, false);
}
}

@ -173,7 +173,7 @@ function process_children(nodes, parent, { visit, state }) {
}
const expression = b.call(
'$.escape',
'$.escape_text',
/** @type {import('estree').Expression} */ (visit(node.expression))
);
state.template.push(t_expression(expression));

@ -150,6 +150,17 @@ export function escape(value, is_attr = false) {
return escaped + str.substring(last);
}
/**
* @template V
* @param {V} value
* @returns {string}
*/
export function escape_text(value) {
const escaped = escape(value);
// If the value is empty, then ensure we put a space so that it creates a text node on the client
return escaped === '' ? ' ' : escaped;
}
/**
* @param {Payload} payload
* @param {(head_payload: Payload['head']) => void} fn

@ -0,0 +1,15 @@
import { flushSync } from 'svelte';
import { test } from '../../test';
export default test({
async test({ assert, target, component }) {
const [b1] = target.querySelectorAll('button');
flushSync(() => {
b1?.click();
});
await Promise.resolve();
assert.deepEqual(component.log, ['onclick']);
}
});

@ -0,0 +1,10 @@
<script>
const {log = []} = $props();
function send() {
log.push("onclick")
}
</script>
{undefined}<hr/>
<button onclick={send}>Send Event</button>
Loading…
Cancel
Save