8000 fix: stable attachments by Rich-Harris · Pull Request #15961 · sveltejs/svelte · GitHub
[go: up one dir, main page]

Skip to content

fix: stable attachments #15961

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
May 28, 2025
Prev Previous commit
Next Next commit
WIP
  • Loading branch information
Rich-Harris committed May 25, 2025
commit 6bb5c279445518b2fa48103c7452ad5d622e623c
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,8 @@ export function RegularElement(node, context) {
const { value, has_state } = build_attribute_value(
attribute.value,
context,
(value, metadata) => (metadata.has_call ? get_expression_id(context.state, value) : value)
(value, metadata) =>
metadata.has_call ? get_expression_id(context.state.expressions, value) : value
);

const update = build_element_attribute_update(node, node_id, name, value, attributes);
Expand Down Expand Up @@ -482,10 +483,11 @@ function setup_select_synchronization(value_binding, context) {

/**
* @param {AST.ClassDirective[]} class_directives
* @param {Expression[]} expressions
* @param {ComponentContext} context
* @return {ObjectExpression | Identifier}
*/
export function build_class_directives_object(class_directives, context) {
export function build_class_directives_object(class_directives, expressions, context) {
let properties = [];
let has_call_or_state = false;

Expand All @@ -497,15 +499,16 @@ export function build_class_directives_object(class_directives, context) {

const directives = b.object(properties);

return has_call_or_state ? get_expression_id(context.state, directives) : directives;
return has_call_or_state ? get_expression_id(expressions, directives) : directives;
}

/**
* @param {AST.StyleDirective[]} style_directives
* @param {Expression[]} expressions
* @param {ComponentContext} context
* @return {ObjectExpression | ArrayExpression}}
*/
export function build_style_directives_object(style_directives, context) {
export function build_style_directives_object(style_directives, expressions, context) {
let normal_properties = [];
let important_properties = [];

Expand All @@ -514,7 +517,7 @@ export function build_style_directives_object(style_directives, context) {
directive.value === true
? build_getter({ name: directive.name, type: 'Identifier' }, context.state)
: build_attribute_value(directive.value, context, (value, metadata) =>
metadata.has_call ? get_expression_id(context.state, value) : value
metadata.has_call ? get_expression_id(expressions, value) : value
).value;
const property = b.init(directive.name, expression);

Expand Down Expand Up @@ -653,7 +656,7 @@ function build_element_special_value_attribute(element, node_id, attribute, cont
? // if is a select with value we will also invoke `init_select` which need a reference before the template effect so we memoize separately
is_select_with_value
? memoize_expression(state, value)
: get_expression_id(state, value)
: get_expression_id(state.expressions, value) // TODO i think this will break in spread, needs to be `expressions`
: value
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export function build_set_attributes(
b.prop(
'init',
b.array([b.id('$.CLASS')]),
build_class_directives_object(class_directives, context)
build_class_directives_object(class_directives, expressions, context)
)
);
}
Expand All @@ -81,7 +81,7 @@ export function build_set_attributes(
b.prop(
'init',
b.array([b.id('$.STYLE')]),
build_style_directives_object(style_directives, context)
build_style_directives_object(style_directives, expressions, context)
)
);
}
Expand Down Expand Up @@ -160,7 +160,7 @@ export function build_set_class(element, node_id, attribute, class_directives, c
value = b.call('$.clsx', value);
}

return metadata.has_call ? get_expression_id(context.state, value) : value;
return metadata.has_call ? get_expression_id(context.state.expressions, value) : value;
});

/** @type {Identifier | undefined} */
Expand All @@ -173,7 +173,7 @@ export function build_set_class(element, node_id, attribute, class_directives, c
let next;

if (class_directives.length) {
next = build_class_directives_object(class_directives, context);
next = build_class_directives_object(class_directives, context.state.expressions, context);
has_state ||= class_directives.some((d) => d.metadata.expression.has_state);

if (has_state) {
Expand Down Expand Up @@ -228,7 +228,7 @@ export function build_set_class(element, node_id, attribute, class_directives, c
*/
export function build_set_style(node_id, attribute, style_directives, context) {
let { value, has_state } = build_attribute_value(attribute.value, context, (value, metadata) =>
metadata.has_call ? get_expression_id(context.state, value) : value
metadata.has_call ? get_expression_id(context.state.expressions, value) : value
);

/** @type {Identifier | undefined} */
Expand All @@ -241,7 +241,7 @@ export function build_set_style(node_id, attribute, style_directives, context) {
let next;

if (style_directives.length) {
next = build_style_directives_object(style_directives, context);
next = build_style_directives_object(style_directives, context.state.expressions, context);
has_state ||= style_directives.some((d) => d.metadata.expression.has_state);

if (has_state) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ export function memoize_expression(state, value) {

/**
*
* @param {ComponentClientTransformState} state
* @param {Expression[]} expressions
* @param {Expression} value
*/
export function get_expression_id(state, value) {
return b.id(`$${state.expressions.push(value) - 1}`);
export function get_expression_id(expressions, value) {
return b.id(`$${expressions.push(value) - 1}`);
}

/**
Expand All @@ -40,7 +40,8 @@ export function build_template_chunk(
values,
visit,
state,
memoize = (value, metadata) => (metadata.has_call ? get_expression_id(state, value) : value)
memoize = (value, metadata) =>
metadata.has_call ? get_expression_id(state.expressions, value) : value
) {
/** @type {Expression[]} */
const expressions = [];
Expand Down
0