Skip to content

Commit

Permalink
more
Browse files Browse the repository at this point in the history
  • Loading branch information
Rich-Harris committed Jan 18, 2025
1 parent 73dfeed commit 3a8f4e0
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ function build_element_attribute_update_assignment(
function build_custom_element_attribute_update_assignment(node_id, attribute, context) {
const state = context.state;
const name = attribute.name; // don't lowercase, as we set the element's property, which might be case sensitive
let value = build_attribute_value(attribute.value, context, (value) => value);
let value = build_attribute_value(attribute.value, context);

// We assume that noone's going to redefine the semantics of the class attribute on custom elements, i.e. it's still used for CSS classes
if (name === 'class' && attribute.metadata.needs_clsx) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
/** @import { ComponentContext } from '../types' */
import * as b from '../../../../utils/builders.js';
import { build_attribute_value } from './shared/element.js';
import { memoize_expression } from './shared/utils.js';

/**
* @param {AST.SlotElement} node
Expand All @@ -29,7 +30,9 @@ export function SlotElement(node, context) {
if (attribute.type === 'SpreadAttribute') {
spreads.push(b.thunk(/** @type {Expression} */ (context.visit(attribute))));
} else if (attribute.type === 'Attribute') {
const value = build_attribute_value(attribute.value, context);
const value = build_attribute_value(attribute.value, context, (value) =>
memoize_expression(context.state, value)
);

if (attribute.name === 'name') {
name = /** @type {Literal} */ (value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { dev, is_ignored } from '../../../../../state.js';
import { get_attribute_chunks, object } from '../../../../../utils/ast.js';
import * as b from '../../../../../utils/builders.js';
import { create_derived } from '../../utils.js';
import { build_bind_this, validate_binding } from '../shared/utils.js';
import { build_bind_this, memoize_expression, validate_binding } from '../shared/utils.js';
import { build_attribute_value } from '../shared/element.js';
import { build_event_handler } from './events.js';
import { determine_slot } from '../../../../../utils/slot.js';
Expand Down Expand Up @@ -132,7 +132,13 @@ export function build_component(node, component_name, context, anchor = context.
} else if (attribute.type === 'Attribute') {
if (attribute.name.startsWith('--')) {
custom_css_props.push(
b.init(attribute.name, build_attribute_value(attribute.value, context))
b.init(
attribute.name,
build_attribute_value(attribute.value, context, (value) =>
// TODO put the derived in the local block
memoize_expression(context.state, value)
)
)
);
continue;
}
Expand All @@ -145,7 +151,9 @@ export function build_component(node, component_name, context, anchor = context.
has_children_prop = true;
}

const value = build_attribute_value(attribute.value, context);
const value = build_attribute_value(attribute.value, context, (value) =>
memoize_expression(context.state, value)
);

if (attribute.metadata.expression.has_state) {
let arg = value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ export function build_set_attributes(

for (const attribute of attributes) {
if (attribute.type === 'Attribute') {
const value = build_attribute_value(attribute.value, context);
const value = build_attribute_value(attribute.value, context, (value) =>
get_expression_id(context.state, value)
);

if (
is_event_attribute(attribute) &&
Expand Down Expand Up @@ -109,7 +111,9 @@ export function build_style_directives(
let value =
directive.value === true
? build_getter({ name: directive.name, type: 'Identifier' }, context.state)
: build_attribute_value(directive.value, context);
: build_attribute_value(directive.value, context, (value) =>
get_expression_id(context.state, value)
);

const update = b.stmt(
b.call(
Expand Down Expand Up @@ -168,18 +172,7 @@ export function build_class_directives(
* @param {(value: Expression) => Expression} memoize
* @returns {Expression}
*/
export function build_attribute_value(
value,
context,
memoize = (value) => {
// TODO this is temporary
const id = b.id(context.state.scope.generate('expression'));
context.state.init.push(
b.const(id, create_derived(context.state, b.thunk(b.logical('??', value, b.literal('')))))
);
return b.call('$.get', id);
}
) {
export function build_attribute_value(value, context, memoize = (value) => value) {
if (value === true) {
return b.literal(true);
}
Expand All @@ -193,11 +186,7 @@ export function build_attribute_value(

let expression = /** @type {Expression} */ (context.visit(chunk.expression));

if (chunk.metadata.expression.has_call) {
expression = memoize(expression);
}

return expression;
return chunk.metadata.expression.has_call ? memoize(expression) : expression;
}

return build_template_chunk(value, context.visit, context.state, memoize).value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,17 @@ import { sanitize_template_string } from '../../../../../utils/sanitize_template
import { regex_is_valid_identifier } from '../../../../patterns.js';
import is_reference from 'is-reference';
import { locator } from '../../../../../state.js';
import { create_derived } from '../../utils.js';

/**
* @param {ComponentClientTransformState} state
* @param {Expression} value
*/
export function memoize_expression(state, value) {
const id = b.id(state.scope.generate('expression'));
state.init.push(b.const(id, create_derived(state, b.thunk(value))));
return b.call('$.get', id);
}

/**
*
Expand Down

0 comments on commit 3a8f4e0

Please sign in to comment.