pull/18771/merge
Bao Nguyen 21 hours ago committed by GitHub
commit 7395b6f54f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: serialize `<textarea>` default values during server rendering

@ -88,6 +88,13 @@ export function build_element_attributes(node, context, transform) {
attributes.push(attribute); attributes.push(attribute);
// deopt to spread at runtime, where we can handle interaction of value/defaultValue etc // deopt to spread at runtime, where we can handle interaction of value/defaultValue etc
has_spread = true; has_spread = true;
} else if (
node.type === 'RegularElement' &&
node.name === 'textarea' &&
attribute.name === 'defaultValue' &&
renders_default_value_as_content(node)
) {
content = b.call('$.escape', build_attribute_value(attribute.value, context, transform));
// the defaultValue/defaultChecked properties don't exist as attributes // the defaultValue/defaultChecked properties don't exist as attributes
} else if (attribute.name !== 'defaultValue' && attribute.name !== 'defaultChecked') { } else if (attribute.name !== 'defaultValue' && attribute.name !== 'defaultChecked') {
if (attribute.name === 'class') { if (attribute.name === 'class') {
@ -293,6 +300,23 @@ export function build_element_attributes(node, context, transform) {
return content; return content;
} }
/**
* A `<textarea>` has no value attribute, so `defaultValue` can only be serialized as its content,
* which is possible when nothing else already provides one.
* @param {AST.RegularElement} node
*/
function renders_default_value_as_content(node) {
return (
node.fragment.nodes.length === 0 &&
!node.attributes.some(
(attribute) =>
attribute.type === 'SpreadAttribute' ||
((attribute.type === 'Attribute' || attribute.type === 'BindDirective') &&
attribute.name === 'value')
)
);
}
/** /**
* @param {AST.RegularElement | AST.SvelteElement} element * @param {AST.RegularElement | AST.SvelteElement} element
* @param {AST.Attribute | AST.BindDirective} attribute * @param {AST.Attribute | AST.BindDirective} attribute

@ -0,0 +1,3 @@
import { test } from '../../test';
export default test({});

@ -0,0 +1,4 @@
<textarea>hello</textarea>
<textarea>world</textarea>
<textarea>content wins</textarea>
<textarea>value wins</textarea>

@ -0,0 +1,8 @@
<script>
let dynamic = 'world';
</script>
<textarea defaultValue="hello"></textarea>
<textarea defaultValue={dynamic}></textarea>
<textarea defaultValue="hello">content wins</textarea>
<textarea defaultValue="hello" value="value wins"></textarea>
Loading…
Cancel
Save