diff --git a/packages/svelte/src/compiler/index.js b/packages/svelte/src/compiler/index.js index d40b8b8935..6ae91a267e 100644 --- a/packages/svelte/src/compiler/index.js +++ b/packages/svelte/src/compiler/index.js @@ -37,8 +37,8 @@ export function compile(source, options) { // resolve the per-component custom renderer, taking `` // into account. The normalized option is always a function returning `string | null | undefined` - // (see `validate-options.js`). A string opts in to a specific renderer module, `null`/`false` - // opts out to plain DOM (while keeping the feature enabled) and `true`/absent inherits whatever + // (see `validate-options.js`). A string opts in to a specific renderer module, `null` + // opts out to plain DOM (while keeping the feature enabled) and an absent option inherits whatever // the global option resolves to. let custom_renderer_option = validated.experimental.customRenderer; @@ -56,7 +56,7 @@ export function compile(source, options) { if (typeof custom_renderer === 'string') { custom_renderer_option = () => custom_renderer; - } else if (custom_renderer === false || custom_renderer === null) { + } else if (custom_renderer === null) { custom_renderer_option = () => null; } } diff --git a/packages/svelte/src/compiler/phases/1-parse/read/options.js b/packages/svelte/src/compiler/phases/1-parse/read/options.js index 847d7cf0b9..b8369816f5 100644 --- a/packages/svelte/src/compiler/phases/1-parse/read/options.js +++ b/packages/svelte/src/compiler/phases/1-parse/read/options.js @@ -37,7 +37,23 @@ export default function read_options(node) { break; // eslint doesn't know this is unnecessary } case 'customRenderer': { - component_options.customRenderer = get_static_value(attribute); + const { value } = attribute; + const chunk = Array.isArray(value) ? value[0] : value; + + if (chunk === true || !chunk || (Array.isArray(value) && value.length !== 1)) { + e.svelte_options_invalid_attribute_value(attribute, 'a string or null'); + } + + if (chunk.type === 'Text') { + component_options.customRenderer = chunk.data; + } else if ( + chunk.expression?.type === 'Literal' && + (typeof chunk.expression.value === 'string' || chunk.expression.value === null) + ) { + component_options.customRenderer = chunk.expression.value; + } else { + e.svelte_options_invalid_attribute_value(attribute, 'a string or null'); + } break; } case 'customElement': { diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js index 6c7f80e37f..03850eb3b7 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js @@ -34,12 +34,10 @@ export function RegularElement(node, context) { context.state.analysis.elements.push(node); // Special case: Move the children of