|
1 |
| -/** @import { Expression, ExpressionStatement, Identifier, MemberExpression, ObjectExpression, Statement } from 'estree' */ |
| 1 | +/** @import { Expression, ExpressionStatement, Identifier, Literal, MemberExpression, ObjectExpression, Statement } from 'estree' */ |
2 | 2 | /** @import { AST } from '#compiler' */
|
3 | 3 | /** @import { SourceLocation } from '#shared' */
|
4 | 4 | /** @import { ComponentClientTransformState, ComponentContext } from '../types' */
|
@@ -596,10 +596,31 @@ function build_element_attribute_update_assignment(element, node_id, attribute,
|
596 | 596 | is_inlinable_attribute(attribute);
|
597 | 597 |
|
598 | 598 | if (can_inline) {
|
599 |
| - // TODO would be great if we could avoid `$.attr` when we know the value |
600 |
| - context.state.template.push( |
601 |
| - b.call('$.attr', b.literal(name), value, is_boolean_attribute(name) && b.true) |
602 |
| - ); |
| 599 | + /** @type {Literal | undefined} */ |
| 600 | + let literal = undefined; |
| 601 | + |
| 602 | + if (value.type === 'Literal') { |
| 603 | + literal = value; |
| 604 | + } else if (value.type === 'Identifier') { |
| 605 | + const binding = context.state.scope.get(value.name); |
| 606 | + if (binding && binding.initial?.type === 'Literal' && !binding.reassigned) { |
| 607 | + literal = binding.initial; |
| 608 | + } |
| 609 | + } |
| 610 | + |
| 611 | + if (literal && escape_html(literal.value, true) === String(literal.value)) { |
| 612 | + if (is_boolean_attribute(name)) { |
| 613 | + if (literal.value) { |
| 614 | + context.state.template.push(` ${name}`); |
| 615 | + } |
| 616 | + } else { |
| 617 | + context.state.template.push(` ${name}="`, value, '"'); |
| 618 | + } |
| 619 | + } else { |
| 620 | + context.state.template.push( |
| 621 | + b.call('$.attr', b.literal(name), value, is_boolean_attribute(name) && b.true) |
| 622 | + ); |
| 623 | + } |
603 | 624 | } else {
|
604 | 625 | state.init.push(update);
|
605 | 626 | }
|
|
0 commit comments