Skip to content

Commit

Permalink
fix: omit unnecessary nullish coallescing in template expressions (#1…
Browse files Browse the repository at this point in the history
…5056)

* omit unnecessary nullish coallescing in template expressions

* add tests
  • Loading branch information
Ocean-OS authored Jan 20, 2025
1 parent 700029b commit 5f6525f
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 1 deletion.
5 changes: 5 additions & 0 deletions .changeset/cuddly-walls-pretend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: omit unnecessary nullish coallescing in template expressions
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,22 @@ export function build_template_chunk(
// extra work in the template_effect (instead we do the work in set_text).
return { value, has_state };
} else {
expressions.push(b.logical('??', value, b.literal('')));
let expression = value;
// only add nullish coallescence if it hasn't been added already
if (value.type === 'LogicalExpression' && value.operator === '??') {
const { right } = value;
// `undefined` isn't a Literal (due to pre-ES5 shenanigans), so the only nullish literal is `null`
// however, you _can_ make a variable called `undefined` in a Svelte component, so we can't just treat it the same way
if (right.type !== 'Literal') {
expression = b.logical('??', value, b.literal(''));
} else if (right.value === null) {
// if they do something weird like `stuff ?? null`, replace `null` with empty string
value.right = b.literal('');
}
} else {
expression = b.logical('??', value, b.literal(''));
}
expressions.push(expression);
}

quasi = b.quasi('', i + 1 === values.length);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { test } from '../../test';

export default test({});
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import 'svelte/internal/disclose-version';
import * as $ from 'svelte/internal/client';

var on_click = (_, count) => $.update(count);
var root = $.template(`<h1></h1> <b></b> <button> </button> <h1></h1>`, 1);

export default function Nullish_coallescence_omittance($$anchor) {
let name = 'world';
let count = $.state(0);
var fragment = root();
var h1 = $.first_child(fragment);

h1.textContent = `Hello, ${name ?? ''}!`;

var b = $.sibling(h1, 2);

b.textContent = `${1 ?? 'stuff'}${2 ?? 'more stuff'}${3 ?? 'even more stuff'}`;

var button = $.sibling(b, 2);

button.__click = [on_click, count];

var text = $.child(button);

$.reset(button);

var h1_1 = $.sibling(button, 2);

h1_1.textContent = `Hello, ${name ?? 'earth' ?? ''}`;
$.template_effect(() => $.set_text(text, `Count is ${$.get(count) ?? ''}`));
$.append($$anchor, fragment);
}

$.delegate(['click']);
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import * as $ from 'svelte/internal/server';

export default function Nullish_coallescence_omittance($$payload) {
let name = 'world';
let count = 0;

$$payload.out += `<h1>Hello, ${$.escape(name)}!</h1> <b>${$.escape(1 ?? 'stuff')}${$.escape(2 ?? 'more stuff')}${$.escape(3 ?? 'even more stuff')}</b> <button>Count is ${$.escape(count)}</button> <h1>Hello, ${$.escape(name ?? 'earth' ?? null)}</h1>`;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<script>
let name = 'world';
let count = $state(0);
</script>
<h1>Hello, {null}{name}!</h1>
<b>{1 ?? 'stuff'}{2 ?? 'more stuff'}{3 ?? 'even more stuff'}</b>
<button onclick={()=>count++}>Count is {count}</button>
<h1>Hello, {name ?? 'earth' ?? null}</h1>

0 comments on commit 5f6525f

Please sign in to comment.