fix: no inlining for conditionals inside legacy template expressions

legacy-conditional-template
Dominic Gannaway 10 months ago
parent 32a1453805
commit 6c60287069

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: no inlining for conditionals inside legacy template expressions

@ -67,6 +67,7 @@ import { TransitionDirective } from './visitors/TransitionDirective.js';
import { UpdateExpression } from './visitors/UpdateExpression.js';
import { UseDirective } from './visitors/UseDirective.js';
import { VariableDeclarator } from './visitors/VariableDeclarator.js';
import { ConditionalExpression } from './visitors/ConditionalExpression.js';
import is_reference from 'is-reference';
import { mark_subtree_dynamic } from './visitors/shared/fragment.js';
@ -177,7 +178,8 @@ const visitors = {
TitleElement,
UpdateExpression,
UseDirective,
VariableDeclarator
VariableDeclarator,
ConditionalExpression
};
/**

@ -30,6 +30,10 @@ export function Attribute(node, context) {
}
}
if (node.name === 'autofocus' || node.name === 'muted') {
mark_subtree_dynamic(context.path);
}
if (node.name.startsWith('on')) {
mark_subtree_dynamic(context.path);
}

@ -0,0 +1,17 @@
/** @import { ConditionalExpression } from 'estree' */
/** @import { Context } from '../types' */
import { mark_subtree_dynamic } from './shared/fragment';
/**
* @param {ConditionalExpression} node
* @param {Context} context
*/
export function ConditionalExpression(node, context) {
// In legacy mode, we treat conditionals inside the template as not inlinable so patterns
// such as BROWSER ? foo : bar, continue to work during hydration
if (context.state.expression && !context.state.analysis.runes) {
context.state.expression.can_inline = false;
mark_subtree_dynamic(context.path);
}
}

@ -75,16 +75,6 @@ export function RegularElement(node, context) {
node.attributes.push(create_attribute('value', child.start, child.end, [child]));
}
if (
node.attributes.some(
(attribute) =>
attribute.type === 'Attribute' &&
(attribute.name === 'autofocus' || attribute.name === 'muted')
)
) {
mark_subtree_dynamic(context.path);
}
const binding = context.state.scope.get(node.name);
if (
binding !== null &&

@ -3,7 +3,7 @@
/** @import { ComponentClientTransformState, ComponentContext } from '../../types' */
import { normalize_attribute } from '../../../../../../utils.js';
import { is_ignored } from '../../../../../state.js';
import { get_attribute_expression, is_event_attribute } from '../../../../../utils/ast.js';
import { is_event_attribute } from '../../../../../utils/ast.js';
import * as b from '../../../../../utils/builders.js';
import { build_getter, create_derived } from '../../utils.js';
import { build_template_chunk, build_update } from './utils.js';

@ -142,10 +142,6 @@ function is_static_element(node) {
return false;
}
if (attribute.name === 'autofocus' || attribute.name === 'muted') {
return false;
}
if (node.name === 'option' && attribute.name === 'value') {
return false;
}

@ -0,0 +1,5 @@
import { test } from '../../test';
export default test({
html: `<div title="client">div</div>`
});

@ -0,0 +1,5 @@
<script lang="ts">
const browser = typeof window !== 'undefined';
</script>
<div title={browser ? "client": "server"}>div</div>
Loading…
Cancel
Save