|
1 | 1 | /** @import { Expression, ExpressionStatement, Identifier, MemberExpression, ObjectExpression, Statement } from 'estree' */ |
2 | | -/** @import { AST } from '#compiler' */ |
| 2 | +/** @import { AST, ExpressionMetadata } from '#compiler' */ |
3 | 3 | /** @import { SourceLocation } from '#shared' */ |
4 | 4 | /** @import { ComponentClientTransformState, ComponentContext } from '../types' */ |
5 | 5 | /** @import { Scope } from '../../../scope' */ |
@@ -501,22 +501,23 @@ function setup_select_synchronization(value_binding, context) { |
501 | 501 | /** |
502 | 502 | * @param {AST.ClassDirective[]} class_directives |
503 | 503 | * @param {ComponentContext} context |
504 | | - * @return {ObjectExpression} |
| 504 | + * @return {ObjectExpression | Identifier} |
505 | 505 | */ |
506 | 506 | export function build_class_directives_object(class_directives, context) { |
507 | 507 | let properties = []; |
508 | 508 |
|
| 509 | + let has_call_or_state = false; |
| 510 | + |
509 | 511 | for (const d of class_directives) { |
510 | 512 | let expression = /** @type Expression */ (context.visit(d.expression)); |
511 | | - |
512 | | - if (d.metadata.expression.has_call) { |
513 | | - expression = get_expression_id(context.state, expression); |
514 | | - } |
515 | | - |
516 | 513 | properties.push(b.init(d.name, expression)); |
| 514 | + has_call_or_state ||= d.metadata.expression.has_call || d.metadata.expression.has_state; |
517 | 515 | } |
518 | | - |
519 | | - return b.object(properties); |
| 516 | + let directives = b.object(properties); |
| 517 | + if (has_call_or_state) { |
| 518 | + return get_expression_id(context.state, directives); |
| 519 | + } |
| 520 | + return directives; |
520 | 521 | } |
521 | 522 |
|
522 | 523 | /** |
@@ -564,15 +565,21 @@ function build_element_attribute_update_assignment( |
564 | 565 |
|
565 | 566 | const is_autofocus = name === 'autofocus'; |
566 | 567 |
|
567 | | - let { value, has_state } = build_attribute_value(attribute.value, context, (value, metadata) => |
568 | | - metadata.has_call |
569 | | - ? // if it's autofocus we will not add this to a template effect so we don't want to get the expression id |
570 | | - // but separately memoize the expression |
571 | | - is_autofocus |
572 | | - ? memoize_expression(state, value) |
573 | | - : get_expression_id(state, value) |
574 | | - : value |
575 | | - ); |
| 568 | + /** @type {(value: Expression, metadata: ExpressionMetadata) => Expression} */ |
| 569 | + let memoize; |
| 570 | + if (is_autofocus) { |
| 571 | + // if it's autofocus we will not add this to a template effect so we don't want to get the expression id |
| 572 | + // but separately memoize the expression |
| 573 | + memoize = (value, metadata) => (metadata.has_call ? memoize_expression(state, value) : value); |
| 574 | + } else if (attribute.metadata.needs_clsx && name === 'class') { |
| 575 | + // if class needs clsx() we do nothing here ! |
| 576 | + // => The entire value will be memoized inside build_set_class() |
| 577 | + memoize = (value) => value; |
| 578 | + } else { |
| 579 | + memoize = (value, metadata) => (metadata.has_call ? get_expression_id(state, value) : value); |
| 580 | + } |
| 581 | + |
| 582 | + let { value, has_state } = build_attribute_value(attribute.value, context, memoize); |
576 | 583 |
|
577 | 584 | if (is_autofocus) { |
578 | 585 | state.init.push(b.stmt(b.call('$.autofocus', node_id, value))); |
|
0 commit comments