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

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

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

@ -7,3 +7,5 @@
<input bind:value={$name}> <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