mirror of https://github.com/sveltejs/svelte
parent
58ce670f32
commit
05e25e772b
@ -0,0 +1,63 @@
|
||||
/** @import { BlockStatement, Expression, Pattern, Statement } from 'estree' */
|
||||
/** @import { EachBlock } from '#compiler' */
|
||||
/** @import { ComponentContext } from '../../types' */
|
||||
import { BLOCK_OPEN_ELSE } from '../../../../../../internal/server/hydration.js';
|
||||
import * as b from '../../../../../utils/builders.js';
|
||||
import { block_close, block_open } from './shared/utils.js';
|
||||
|
||||
/**
|
||||
* @param {EachBlock} node
|
||||
* @param {ComponentContext} context
|
||||
*/
|
||||
export function EachBlock(node, context) {
|
||||
const state = context.state;
|
||||
|
||||
const each_node_meta = node.metadata;
|
||||
const collection = /** @type {Expression} */ (context.visit(node.expression));
|
||||
const item = each_node_meta.item;
|
||||
const index =
|
||||
each_node_meta.contains_group_binding || !node.index ? each_node_meta.index : b.id(node.index);
|
||||
|
||||
const array_id = state.scope.root.unique('each_array');
|
||||
state.init.push(b.const(array_id, b.call('$.ensure_array_like', collection)));
|
||||
|
||||
/** @type {Statement[]} */
|
||||
const each = [b.const(item, b.member(array_id, index, true))];
|
||||
|
||||
if (node.context.type !== 'Identifier') {
|
||||
each.push(b.const(/** @type {Pattern} */ (node.context), item));
|
||||
}
|
||||
if (index.name !== node.index && node.index != null) {
|
||||
each.push(b.let(node.index, index));
|
||||
}
|
||||
|
||||
each.push(.../** @type {BlockStatement} */ (context.visit(node.body)).body);
|
||||
|
||||
const for_loop = b.for(
|
||||
b.let(index, b.literal(0)),
|
||||
b.binary('<', index, b.member(array_id, b.id('length'))),
|
||||
b.update('++', index, false),
|
||||
b.block(each)
|
||||
);
|
||||
|
||||
if (node.fallback) {
|
||||
const open = b.stmt(b.assignment('+=', b.id('$$payload.out'), block_open));
|
||||
|
||||
const fallback = /** @type {BlockStatement} */ (context.visit(node.fallback));
|
||||
|
||||
fallback.body.unshift(
|
||||
b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(BLOCK_OPEN_ELSE)))
|
||||
);
|
||||
|
||||
state.template.push(
|
||||
b.if(
|
||||
b.binary('!==', b.member(array_id, b.id('length')), b.literal(0)),
|
||||
b.block([open, for_loop]),
|
||||
fallback
|
||||
),
|
||||
block_close
|
||||
);
|
||||
} else {
|
||||
state.template.push(block_open, for_loop, block_close);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
/** @import { BlockStatement, Expression } from 'estree' */
|
||||
/** @import { IfBlock } from '#compiler' */
|
||||
/** @import { ComponentContext } from '../../types' */
|
||||
import { BLOCK_OPEN_ELSE } from '../../../../../../internal/server/hydration.js';
|
||||
import * as b from '../../../../../utils/builders.js';
|
||||
import { block_close, block_open } from './shared/utils.js';
|
||||
|
||||
/**
|
||||
* @param {IfBlock} node
|
||||
* @param {ComponentContext} context
|
||||
*/
|
||||
export function IfBlock(node, context) {
|
||||
const test = /** @type {Expression} */ (context.visit(node.test));
|
||||
|
||||
const consequent = /** @type {BlockStatement} */ (context.visit(node.consequent));
|
||||
|
||||
const alternate = node.alternate
|
||||
? /** @type {BlockStatement} */ (context.visit(node.alternate))
|
||||
: b.block([]);
|
||||
|
||||
consequent.body.unshift(b.stmt(b.assignment('+=', b.id('$$payload.out'), block_open)));
|
||||
|
||||
alternate.body.unshift(
|
||||
b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(BLOCK_OPEN_ELSE)))
|
||||
);
|
||||
|
||||
context.state.template.push(b.if(test, consequent, alternate), block_close);
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
/** @import { BlockStatement, Expression } from 'estree' */
|
||||
/** @import { SvelteElement } from '#compiler' */
|
||||
/** @import { ComponentContext } from '../../types' */
|
||||
import * as b from '../../../../../utils/builders.js';
|
||||
import { determine_namespace_for_children } from '../../../utils.js';
|
||||
import { serialize_element_attributes } from './shared/element.js';
|
||||
import { serialize_template } from './shared/utils.js';
|
||||
|
||||
/**
|
||||
* @param {SvelteElement} node
|
||||
* @param {ComponentContext} context
|
||||
*/
|
||||
export function SvelteElement(node, context) {
|
||||
let tag = /** @type {Expression} */ (context.visit(node.tag));
|
||||
if (tag.type !== 'Identifier') {
|
||||
const tag_id = context.state.scope.generate('$$tag');
|
||||
context.state.init.push(b.const(tag_id, tag));
|
||||
tag = b.id(tag_id);
|
||||
}
|
||||
|
||||
if (context.state.options.dev) {
|
||||
if (node.fragment.nodes.length > 0) {
|
||||
context.state.init.push(b.stmt(b.call('$.validate_void_dynamic_element', b.thunk(tag))));
|
||||
}
|
||||
context.state.init.push(b.stmt(b.call('$.validate_dynamic_element_tag', b.thunk(tag))));
|
||||
}
|
||||
|
||||
const state = {
|
||||
...context.state,
|
||||
getteres: { ...context.state.getters },
|
||||
namespace: determine_namespace_for_children(node, context.state.namespace),
|
||||
template: [],
|
||||
init: []
|
||||
};
|
||||
|
||||
serialize_element_attributes(node, { ...context, state });
|
||||
|
||||
if (context.state.options.dev) {
|
||||
context.state.template.push(b.stmt(b.call('$.push_element', tag, b.id('$$payload'))));
|
||||
}
|
||||
|
||||
const attributes = b.block([...state.init, ...serialize_template(state.template)]);
|
||||
const children = /** @type {BlockStatement} */ (context.visit(node.fragment, state));
|
||||
|
||||
context.state.template.push(
|
||||
b.stmt(
|
||||
b.call(
|
||||
'$.element',
|
||||
b.id('$$payload'),
|
||||
tag,
|
||||
attributes.body.length > 0 && b.thunk(attributes),
|
||||
children.body.length > 0 && b.thunk(children)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if (context.state.options.dev) {
|
||||
context.state.template.push(b.stmt(b.call('$.pop_element')));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in new issue