fix: transform textarea and contenteditable binding expressions (#10187)

fixes #10185
pull/10190/head
Simon H 10 months ago committed by GitHub
parent d509de2503
commit 1b675c0264
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,5 @@
---
"svelte": patch
---
fix: transform textarea and contenteditable binding expressions

@ -2595,16 +2595,14 @@ export const template_visitors = {
);
}
const getter = b.thunk(
/** @type {import('estree').Expression} */ (context.visit(node.expression))
);
const getter = b.thunk(/** @type {import('estree').Expression} */ (visit(node.expression)));
const assignment = b.assignment('=', node.expression, b.id('$$value'));
const setter = b.arrow(
[b.id('$$value')],
serialize_set_binding(
assignment,
context,
() => /** @type {import('estree').Expression} */ (context.visit(assignment)),
() => /** @type {import('estree').Expression} */ (visit(assignment)),
{
skip_proxy_and_freeze: true
}
@ -2767,9 +2765,7 @@ export const template_visitors = {
group_getter = b.thunk(
b.block([
b.stmt(serialize_attribute_value(value, context)[1]),
b.return(
/** @type {import('estree').Expression} */ (context.visit(node.expression))
)
b.return(/** @type {import('estree').Expression} */ (visit(node.expression)))
])
);
}

@ -1452,9 +1452,6 @@ const template_visitors = {
context.state.init.push(b.stmt(b.call('$.add_snippet_symbol', node.expression)));
}
},
BindDirective(node, context) {
// TODO
},
Component(node, context) {
const state = context.state;
const [dec, id] = serialize_anchor(state);
@ -1694,9 +1691,19 @@ function serialize_element_attributes(node, context) {
if (binding?.omit_in_ssr) continue;
if (ContentEditableBindings.includes(attribute.name)) {
content = { escape: false, expression: attribute.expression };
content = {
escape: false,
expression: /** @type {import('estree').Expression} */ (
context.visit(attribute.expression)
)
};
} else if (attribute.name === 'value' && node.name === 'textarea') {
content = { escape: true, expression: attribute.expression };
content = {
escape: true,
expression: /** @type {import('estree').Expression} */ (
context.visit(attribute.expression)
)
};
} else if (attribute.name === 'group') {
const value_attribute = /** @type {import('#compiler').Attribute | undefined} */ (
node.attributes.find((attr) => attr.type === 'Attribute' && attr.name === 'value')

@ -4,11 +4,15 @@ export default test({
html: `
<input>
<p>hello world</p>
<textarea></textarea>
<div contenteditable="true">world</div>
`,
ssrHtml: `
<input value="world">
<p>hello world</p>
<textarea>world</textarea>
<div contenteditable="true">world</div>
`,
async test({ assert, component, target, window }) {
@ -34,6 +38,8 @@ export default test({
`
<input>
<p>hello everybody</p>
<textarea></textarea>
<div contenteditable="true">everybody</div>
`
);
@ -44,6 +50,8 @@ export default test({
`
<input>
<p>hello goodbye</p>
<textarea></textarea>
<div contenteditable="true">goodbye</div>
`
);

@ -6,4 +6,6 @@
</script>
<input bind:value={$name}>
<p>hello {$name}</p>
<p>hello {$name}</p>
<textarea bind:value={$name} />
<div contenteditable="true" bind:innerHTML={$name}></div>

Loading…
Cancel
Save