diff --git a/.changeset/tired-cities-wink.md b/.changeset/tired-cities-wink.md new file mode 100644 index 0000000000..a319b5b2b0 --- /dev/null +++ b/.changeset/tired-cities-wink.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: render boolean attribute values as empty strings for XHTML compliance diff --git a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js index 720522beaf..f651586dd8 100644 --- a/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js +++ b/packages/svelte/src/compiler/phases/3-transform/client/visitors/RegularElement.js @@ -256,10 +256,7 @@ export function RegularElement(node, context) { } if (name !== 'class' || value) { - context.state.template.set_prop( - attribute.name, - is_boolean_attribute(name) && value === true ? undefined : value === true ? '' : value - ); + context.state.template.set_prop(attribute.name, value === true ? '' : value); } } else if (name === 'autofocus') { let { value } = build_attribute_value(attribute.value, context); diff --git a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/element.js b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/element.js index 979efef6b9..f4f491c056 100644 --- a/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/element.js +++ b/packages/svelte/src/compiler/phases/3-transform/server/visitors/shared/element.js @@ -235,13 +235,7 @@ export function build_element_attributes(node, context, transform) { if (name !== 'class' || literal_value) { context.state.template.push( - b.literal( - ` ${attribute.name}${ - is_boolean_attribute(name) && literal_value === true - ? '' - : `="${literal_value === true ? '' : String(literal_value)}"` - }` - ) + b.literal(` ${attribute.name}="${literal_value === true ? '' : String(literal_value)}"`) ); } diff --git a/packages/svelte/tests/runtime-xhtml/samples/boolean-attributes/_config.js b/packages/svelte/tests/runtime-xhtml/samples/boolean-attributes/_config.js index f965e04b02..f47bee71df 100644 --- a/packages/svelte/tests/runtime-xhtml/samples/boolean-attributes/_config.js +++ b/packages/svelte/tests/runtime-xhtml/samples/boolean-attributes/_config.js @@ -1,5 +1,3 @@ import { test } from '../../test'; -export default test({ - skip: true -}); +export default test({}); diff --git a/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/server/index.svelte.js b/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/server/index.svelte.js index 7a9f6193d7..b1babb514c 100644 --- a/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/server/index.svelte.js +++ b/packages/svelte/tests/snapshot/samples/skip-static-subtree/_expected/server/index.svelte.js @@ -3,7 +3,7 @@ import * as $ from 'svelte/internal/server'; export default function Skip_static_subtree($$renderer, $$props) { let { title, content } = $$props; - $$renderer.push(`

${$.escape(title)}

we don't need to traverse these nodes

or

these

ones

${$.html(content)}

these

trailing

nodes

can

be

completely

ignored