diff --git a/packages/svelte/src/compiler/phases/2-analyze/index.js b/packages/svelte/src/compiler/phases/2-analyze/index.js index a96652d60b..7e69096010 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/index.js +++ b/packages/svelte/src/compiler/phases/2-analyze/index.js @@ -710,7 +710,7 @@ export function analyze_component(root, source, options) { // mark nodes as scoped/unused/empty etc for (const element of analysis.elements) { - prune(analysis.css.ast, element); + prune(analysis.css.ast, element.node); } const { comment } = analysis.css.ast.content; @@ -724,18 +724,18 @@ export function analyze_component(root, source, options) { warn_unused(analysis.css.ast); } - outer: for (const element of analysis.elements) { - if (element.type === 'RenderTag') continue; + outer: for (const { node } of analysis.elements) { + if (node.type === 'RenderTag') continue; - if (element.metadata.scoped) { + if (node.metadata.scoped) { // Dynamic elements in dom mode always use spread for attributes and therefore shouldn't have a class attribute added to them // TODO this happens during the analysis phase, which shouldn't know anything about client vs server - if (element.type === 'SvelteElement' && options.generate === 'client') continue; + if (node.type === 'SvelteElement' && options.generate === 'client') continue; /** @type {AST.Attribute | undefined} */ let class_attribute = undefined; - for (const attribute of element.attributes) { + for (const attribute of node.attributes) { if (attribute.type === 'SpreadAttribute') { // The spread method appends the hash to the end of the class attribute on its own continue outer; @@ -768,7 +768,7 @@ export function analyze_component(root, source, options) { } } } else { - element.attributes.push( + node.attributes.push( create_attribute('class', -1, -1, [ { type: 'Text', @@ -780,8 +780,8 @@ export function analyze_component(root, source, options) { } ]) ); - if (is_custom_element_node(element) && element.attributes.length === 1) { - mark_subtree_dynamic(element.metadata.path); + if (is_custom_element_node(node) && node.attributes.length === 1) { + mark_subtree_dynamic(node.metadata.path); } } } diff --git a/packages/svelte/src/compiler/phases/2-analyze/visitors/ExpressionTag.js b/packages/svelte/src/compiler/phases/2-analyze/visitors/ExpressionTag.js index 32c8d2ca36..7e21d5ca14 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/ExpressionTag.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/ExpressionTag.js @@ -9,7 +9,9 @@ import { mark_subtree_dynamic } from './shared/fragment.js'; * @param {Context} context */ export function ExpressionTag(node, context) { - if (node.parent && context.state.parent_element) { + const in_attribute = context.path.at(-1)?.type === 'Attribute'; + + if (!in_attribute && context.state.parent_element) { if (!is_tag_valid_with_parent('#text', context.state.parent_element)) { e.node_invalid_placement(node, '`{expression}`', context.state.parent_element); } 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 7d1c4aaeaa..af54f18035 100644 --- a/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js +++ b/packages/svelte/src/compiler/phases/2-analyze/visitors/RegularElement.js @@ -20,11 +20,11 @@ import { mark_subtree_dynamic } from './shared/fragment.js'; export function RegularElement(node, context) { validate_element(node, context); - check_element(node, context.state); + check_element(node, context); node.metadata.path = [...context.path]; - context.state.analysis.elements.push(node); + context.state.analysis.elements.push({ node, path: context.path }); // Special case: Move the children of