|
|
|
@ -11,7 +11,7 @@ import {
|
|
|
|
import { is_ignored } from '../../../../state.js';
|
|
|
|
import { is_ignored } from '../../../../state.js';
|
|
|
|
import { is_event_attribute, is_text_attribute } from '../../../../utils/ast.js';
|
|
|
|
import { is_event_attribute, is_text_attribute } from '../../../../utils/ast.js';
|
|
|
|
import * as b from '#compiler/builders';
|
|
|
|
import * as b from '#compiler/builders';
|
|
|
|
import { create_attribute, is_custom_element_node } from '../../../nodes.js';
|
|
|
|
import { create_attribute, ExpressionMetadata, is_custom_element_node } from '../../../nodes.js';
|
|
|
|
import { clean_nodes, determine_namespace_for_children } from '../../utils.js';
|
|
|
|
import { clean_nodes, determine_namespace_for_children } from '../../utils.js';
|
|
|
|
import { build_getter } from '../utils.js';
|
|
|
|
import { build_getter } from '../utils.js';
|
|
|
|
import {
|
|
|
|
import {
|
|
|
|
@ -267,10 +267,7 @@ export function RegularElement(node, context) {
|
|
|
|
const { value, has_state } = build_attribute_value(
|
|
|
|
const { value, has_state } = build_attribute_value(
|
|
|
|
attribute.value,
|
|
|
|
attribute.value,
|
|
|
|
context,
|
|
|
|
context,
|
|
|
|
(value, metadata) =>
|
|
|
|
(value, metadata) => context.state.memoizer.add(value, metadata)
|
|
|
|
metadata.has_call || metadata.has_await
|
|
|
|
|
|
|
|
? context.state.memoizer.add(value, metadata.has_await)
|
|
|
|
|
|
|
|
: value
|
|
|
|
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
const update = build_element_attribute_update(node, node_id, name, value, attributes);
|
|
|
|
const update = build_element_attribute_update(node, node_id, name, value, attributes);
|
|
|
|
@ -487,11 +484,25 @@ function setup_select_synchronization(value_binding, context) {
|
|
|
|
);
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @param {ExpressionMetadata} target
|
|
|
|
|
|
|
|
* @param {ExpressionMetadata} source
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
function merge_metadata(target, source) {
|
|
|
|
|
|
|
|
target.has_assignment ||= source.has_assignment;
|
|
|
|
|
|
|
|
target.has_await ||= source.has_await;
|
|
|
|
|
|
|
|
target.has_call ||= source.has_call;
|
|
|
|
|
|
|
|
target.has_member_expression ||= source.has_member_expression;
|
|
|
|
|
|
|
|
target.has_state ||= source.has_state;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const r of source.references) target.references.add(r);
|
|
|
|
|
|
|
|
for (const b of source.dependencies) target.dependencies.add(b);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @param {AST.ClassDirective[]} class_directives
|
|
|
|
* @param {AST.ClassDirective[]} class_directives
|
|
|
|
* @param {ComponentContext} context
|
|
|
|
* @param {ComponentContext} context
|
|
|
|
* @param {Memoizer} memoizer
|
|
|
|
* @param {Memoizer} memoizer
|
|
|
|
* @return {ObjectExpression | Identifier}
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export function build_class_directives_object(
|
|
|
|
export function build_class_directives_object(
|
|
|
|
class_directives,
|
|
|
|
class_directives,
|
|
|
|
@ -499,26 +510,25 @@ export function build_class_directives_object(
|
|
|
|
memoizer = context.state.memoizer
|
|
|
|
memoizer = context.state.memoizer
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
let properties = [];
|
|
|
|
let properties = [];
|
|
|
|
let has_call_or_state = false;
|
|
|
|
|
|
|
|
let has_await = false;
|
|
|
|
const metadata = new ExpressionMetadata();
|
|
|
|
|
|
|
|
|
|
|
|
for (const d of class_directives) {
|
|
|
|
for (const d of class_directives) {
|
|
|
|
|
|
|
|
merge_metadata(metadata, d.metadata.expression);
|
|
|
|
|
|
|
|
|
|
|
|
const expression = /** @type Expression */ (context.visit(d.expression));
|
|
|
|
const expression = /** @type Expression */ (context.visit(d.expression));
|
|
|
|
properties.push(b.init(d.name, expression));
|
|
|
|
properties.push(b.init(d.name, expression));
|
|
|
|
has_call_or_state ||= d.metadata.expression.has_call || d.metadata.expression.has_state;
|
|
|
|
|
|
|
|
has_await ||= d.metadata.expression.has_await;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const directives = b.object(properties);
|
|
|
|
const directives = b.object(properties);
|
|
|
|
|
|
|
|
|
|
|
|
return has_call_or_state || has_await ? memoizer.add(directives, has_await) : directives;
|
|
|
|
return memoizer.add(directives, metadata);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @param {AST.StyleDirective[]} style_directives
|
|
|
|
* @param {AST.StyleDirective[]} style_directives
|
|
|
|
* @param {ComponentContext} context
|
|
|
|
* @param {ComponentContext} context
|
|
|
|
* @param {Memoizer} memoizer
|
|
|
|
* @param {Memoizer} memoizer
|
|
|
|
* @return {ObjectExpression | ArrayExpression | Identifier}}
|
|
|
|
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export function build_style_directives_object(
|
|
|
|
export function build_style_directives_object(
|
|
|
|
style_directives,
|
|
|
|
style_directives,
|
|
|
|
@ -528,10 +538,11 @@ export function build_style_directives_object(
|
|
|
|
const normal = b.object([]);
|
|
|
|
const normal = b.object([]);
|
|
|
|
const important = b.object([]);
|
|
|
|
const important = b.object([]);
|
|
|
|
|
|
|
|
|
|
|
|
let has_call_or_state = false;
|
|
|
|
const metadata = new ExpressionMetadata();
|
|
|
|
let has_await = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const d of style_directives) {
|
|
|
|
for (const d of style_directives) {
|
|
|
|
|
|
|
|
merge_metadata(metadata, d.metadata.expression);
|
|
|
|
|
|
|
|
|
|
|
|
const expression =
|
|
|
|
const expression =
|
|
|
|
d.value === true
|
|
|
|
d.value === true
|
|
|
|
? build_getter(b.id(d.name), context.state)
|
|
|
|
? build_getter(b.id(d.name), context.state)
|
|
|
|
@ -539,14 +550,11 @@ export function build_style_directives_object(
|
|
|
|
|
|
|
|
|
|
|
|
const object = d.modifiers.includes('important') ? important : normal;
|
|
|
|
const object = d.modifiers.includes('important') ? important : normal;
|
|
|
|
object.properties.push(b.init(d.name, expression));
|
|
|
|
object.properties.push(b.init(d.name, expression));
|
|
|
|
|
|
|
|
|
|
|
|
has_call_or_state ||= d.metadata.expression.has_call || d.metadata.expression.has_state;
|
|
|
|
|
|
|
|
has_await ||= d.metadata.expression.has_await;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const directives = important.properties.length ? b.array([normal, important]) : normal;
|
|
|
|
const directives = important.properties.length ? b.array([normal, important]) : normal;
|
|
|
|
|
|
|
|
|
|
|
|
return has_call_or_state || has_await ? memoizer.add(directives, has_await) : directives;
|
|
|
|
return memoizer.add(directives, metadata);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
@ -675,7 +683,7 @@ function build_element_special_value_attribute(
|
|
|
|
element === 'select' && attribute.value !== true && !is_text_attribute(attribute);
|
|
|
|
element === 'select' && attribute.value !== true && !is_text_attribute(attribute);
|
|
|
|
|
|
|
|
|
|
|
|
const { value, has_state } = build_attribute_value(attribute.value, context, (value, metadata) =>
|
|
|
|
const { value, has_state } = build_attribute_value(attribute.value, context, (value, metadata) =>
|
|
|
|
metadata.has_call || metadata.has_await ? state.memoizer.add(value, metadata.has_await) : value
|
|
|
|
state.memoizer.add(value, metadata)
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
const evaluated = context.state.scope.evaluate(value);
|
|
|
|
const evaluated = context.state.scope.evaluate(value);
|
|
|
|
|