Skip to content

Commit 05e25e7

Browse files
committed
more
1 parent 58ce670 commit 05e25e7

File tree

4 files changed

+158
-124
lines changed

4 files changed

+158
-124
lines changed

packages/svelte/src/compiler/phases/3-transform/server/transform-server.js

Lines changed: 7 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,25 @@ import { set_scope, get_rune } from '../../scope.js';
99
import { extract_identifiers, extract_paths, is_expression_async } from '../../../utils/ast.js';
1010
import * as b from '../../../utils/builders.js';
1111
import is_reference from 'is-reference';
12-
import { determine_namespace_for_children, transform_inspect_rune } from '../utils.js';
12+
import { transform_inspect_rune } from '../utils.js';
1313
import { is_element_node } from '../../nodes.js';
14-
import { BLOCK_OPEN_ELSE } from '../../../../internal/server/hydration.js';
1514
import { filename } from '../../../state.js';
1615
import { render_stylesheet } from '../css/index.js';
1716
import { ConstTag } from './visitors/template/ConstTag.js';
1817
import { DebugTag } from './visitors/template/DebugTag.js';
18+
import { EachBlock } from './visitors/template/EachBlock.js';
1919
import { Fragment } from './visitors/template/Fragment.js';
2020
import { HtmlTag } from './visitors/template/HtmlTag.js';
21+
import { IfBlock } from './visitors/template/IfBlock.js';
2122
import { RegularElement } from './visitors/template/RegularElement.js';
2223
import { RenderTag } from './visitors/template/RenderTag.js';
24+
import { SvelteElement } from './visitors/template/SvelteElement.js';
2325
import {
24-
block_close,
25-
block_open,
2626
empty_comment,
2727
process_children,
2828
serialize_attribute_value,
2929
serialize_template
3030
} from './visitors/template/shared/utils.js';
31-
import { serialize_element_attributes } from './visitors/template/shared/element.js';
3231

3332
/**
3433
* @param {VariableDeclarator} declarator
@@ -832,125 +831,9 @@ const template_visitors = {
832831
DebugTag,
833832
RenderTag,
834833
RegularElement,
835-
SvelteElement(node, context) {
836-
let tag = /** @type {Expression} */ (context.visit(node.tag));
837-
if (tag.type !== 'Identifier') {
838-
const tag_id = context.state.scope.generate('$$tag');
839-
context.state.init.push(b.const(tag_id, tag));
840-
tag = b.id(tag_id);
841-
}
842-
843-
if (context.state.options.dev) {
844-
if (node.fragment.nodes.length > 0) {
845-
context.state.init.push(b.stmt(b.call('$.validate_void_dynamic_element', b.thunk(tag))));
846-
}
847-
context.state.init.push(b.stmt(b.call('$.validate_dynamic_element_tag', b.thunk(tag))));
848-
}
849-
850-
const state = {
851-
...context.state,
852-
getteres: { ...context.state.getters },
853-
namespace: determine_namespace_for_children(node, context.state.namespace),
854-
template: [],
855-
init: []
856-
};
857-
858-
serialize_element_attributes(node, { ...context, state });
859-
860-
if (context.state.options.dev) {
861-
context.state.template.push(b.stmt(b.call('$.push_element', tag, b.id('$$payload'))));
862-
}
863-
864-
const attributes = b.block([...state.init, ...serialize_template(state.template)]);
865-
const children = /** @type {BlockStatement} */ (context.visit(node.fragment, state));
866-
867-
context.state.template.push(
868-
b.stmt(
869-
b.call(
870-
'$.element',
871-
b.id('$$payload'),
872-
tag,
873-
attributes.body.length > 0 && b.thunk(attributes),
874-
children.body.length > 0 && b.thunk(children)
875-
)
876-
)
877-
);
878-
879-
if (context.state.options.dev) {
880-
context.state.template.push(b.stmt(b.call('$.pop_element')));
881-
}
882-
},
883-
EachBlock(node, context) {
884-
const state = context.state;
885-
886-
const each_node_meta = node.metadata;
887-
const collection = /** @type {Expression} */ (context.visit(node.expression));
888-
const item = each_node_meta.item;
889-
const index =
890-
each_node_meta.contains_group_binding || !node.index
891-
? each_node_meta.index
892-
: b.id(node.index);
893-
894-
const array_id = state.scope.root.unique('each_array');
895-
state.init.push(b.const(array_id, b.call('$.ensure_array_like', collection)));
896-
897-
/** @type {Statement[]} */
898-
const each = [b.const(item, b.member(array_id, index, true))];
899-
900-
if (node.context.type !== 'Identifier') {
901-
each.push(b.const(/** @type {Pattern} */ (node.context), item));
902-
}
903-
if (index.name !== node.index && node.index != null) {
904-
each.push(b.let(node.index, index));
905-
}
906-
907-
each.push(.../** @type {BlockStatement} */ (context.visit(node.body)).body);
908-
909-
const for_loop = b.for(
910-
b.let(index, b.literal(0)),
911-
b.binary('<', index, b.member(array_id, b.id('length'))),
912-
b.update('++', index, false),
913-
b.block(each)
914-
);
915-
916-
if (node.fallback) {
917-
const open = b.stmt(b.assignment('+=', b.id('$$payload.out'), block_open));
918-
919-
const fallback = /** @type {BlockStatement} */ (context.visit(node.fallback));
920-
921-
fallback.body.unshift(
922-
b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(BLOCK_OPEN_ELSE)))
923-
);
924-
925-
state.template.push(
926-
b.if(
927-
b.binary('!==', b.member(array_id, b.id('length')), b.literal(0)),
928-
b.block([open, for_loop]),
929-
fallback
930-
),
931-
block_close
932-
);
933-
} else {
934-
state.template.push(block_open, for_loop, block_close);
935-
}
936-
},
937-
IfBlock(node, context) {
938-
const test = /** @type {Expression} */ (context.visit(node.test));
939-
940-
const consequent = /** @type {BlockStatement} */ (context.visit(node.consequent));
941-
942-
const alternate = node.alternate
943-
? /** @type {BlockStatement} */ (context.visit(node.alternate))
944-
: b.block([]);
945-
946-
consequent.body.unshift(b.stmt(b.assignment('+=', b.id('$$payload.out'), block_open)));
947-
948-
alternate.body.unshift(
949-
b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(BLOCK_OPEN_ELSE)))
950-
);
951-
952-
context.state.template.push(b.if(test, consequent, alternate), block_close);
953-
},
834+
SvelteElement,
835+
EachBlock,
836+
IfBlock,
954837
AwaitBlock(node, context) {
955838
context.state.template.push(
956839
empty_comment,
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/** @import { BlockStatement, Expression, Pattern, Statement } from 'estree' */
2+
/** @import { EachBlock } from '#compiler' */
3+
/** @import { ComponentContext } from '../../types' */
4+
import { BLOCK_OPEN_ELSE } from '../../../../../../internal/server/hydration.js';
5+
import * as b from '../../../../../utils/builders.js';
6+
import { block_close, block_open } from './shared/utils.js';
7+
8+
/**
9+
* @param {EachBlock} node
10+
* @param {ComponentContext} context
11+
*/
12+
export function EachBlock(node, context) {
13+
const state = context.state;
14+
15+
const each_node_meta = node.metadata;
16+
const collection = /** @type {Expression} */ (context.visit(node.expression));
17+
const item = each_node_meta.item;
18+
const index =
19+
each_node_meta.contains_group_binding || !node.index ? each_node_meta.index : b.id(node.index);
20+
21+
const array_id = state.scope.root.unique('each_array');
22+
state.init.push(b.const(array_id, b.call('$.ensure_array_like', collection)));
23+
24+
/** @type {Statement[]} */
25+
const each = [b.const(item, b.member(array_id, index, true))];
26+
27+
if (node.context.type !== 'Identifier') {
28+
each.push(b.const(/** @type {Pattern} */ (node.context), item));
29+
}
30+
if (index.name !== node.index && node.index != null) {
31+
each.push(b.let(node.index, index));
32+
}
33+
34+
each.push(.../** @type {BlockStatement} */ (context.visit(node.body)).body);
35+
36+
const for_loop = b.for(
37+
b.let(index, b.literal(0)),
38+
b.binary('<', index, b.member(array_id, b.id('length'))),
39+
b.update('++', index, false),
40+
b.block(each)
41+
);
42+
43+
if (node.fallback) {
44+
const open = b.stmt(b.assignment('+=', b.id('$$payload.out'), block_open));
45+
46+
const fallback = /** @type {BlockStatement} */ (context.visit(node.fallback));
47+
48+
fallback.body.unshift(
49+
b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(BLOCK_OPEN_ELSE)))
50+
);
51+
52+
state.template.push(
53+
b.if(
54+
b.binary('!==', b.member(array_id, b.id('length')), b.literal(0)),
55+
b.block([open, for_loop]),
56+
fallback
57+
),
58+
block_close
59+
);
60+
} else {
61+
state.template.push(block_open, for_loop, block_close);
62+
}
63+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/** @import { BlockStatement, Expression } from 'estree' */
2+
/** @import { IfBlock } from '#compiler' */
3+
/** @import { ComponentContext } from '../../types' */
4+
import { BLOCK_OPEN_ELSE } from '../../../../../../internal/server/hydration.js';
5+
import * as b from '../../../../../utils/builders.js';
6+
import { block_close, block_open } from './shared/utils.js';
7+
8+
/**
9+
* @param {IfBlock} node
10+
* @param {ComponentContext} context
11+
*/
12+
export function IfBlock(node, context) {
13+
const test = /** @type {Expression} */ (context.visit(node.test));
14+
15+
const consequent = /** @type {BlockStatement} */ (context.visit(node.consequent));
16+
17+
const alternate = node.alternate
18+
? /** @type {BlockStatement} */ (context.visit(node.alternate))
19+
: b.block([]);
20+
21+
consequent.body.unshift(b.stmt(b.assignment('+=', b.id('$$payload.out'), block_open)));
22+
23+
alternate.body.unshift(
24+
b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(BLOCK_OPEN_ELSE)))
25+
);
26+
27+
context.state.template.push(b.if(test, consequent, alternate), block_close);
28+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/** @import { BlockStatement, Expression } from 'estree' */
2+
/** @import { SvelteElement } from '#compiler' */
3+
/** @import { ComponentContext } from '../../types' */
4+
import * as b from '../../../../../utils/builders.js';
5+
import { determine_namespace_for_children } from '../../../utils.js';
6+
import { serialize_element_attributes } from './shared/element.js';
7+
import { serialize_template } from './shared/utils.js';
8+
9+
/**
10+
* @param {SvelteElement} node
11+
* @param {ComponentContext} context
12+
*/
13+
export function SvelteElement(node, context) {
14+
let tag = /** @type {Expression} */ (context.visit(node.tag));
15+
if (tag.type !== 'Identifier') {
16+
const tag_id = context.state.scope.generate('$$tag');
17+
context.state.init.push(b.const(tag_id, tag));
18+
tag = b.id(tag_id);
19+
}
20+
21+
if (context.state.options.dev) {
22+
if (node.fragment.nodes.length > 0) {
23+
context.state.init.push(b.stmt(b.call('$.validate_void_dynamic_element', b.thunk(tag))));
24+
}
25+
context.state.init.push(b.stmt(b.call('$.validate_dynamic_element_tag', b.thunk(tag))));
26+
}
27+
28+
const state = {
29+
...context.state,
30+
getteres: { ...context.state.getters },
31+
namespace: determine_namespace_for_children(node, context.state.namespace),
32+
template: [],
33+
init: []
34+
};
35+
36+
serialize_element_attributes(node, { ...context, state });
37+
38+
if (context.state.options.dev) {
39+
context.state.template.push(b.stmt(b.call('$.push_element', tag, b.id('$$payload'))));
40+
}
41+
42+
const attributes = b.block([...state.init, ...serialize_template(state.template)]);
43+
const children = /** @type {BlockStatement} */ (context.visit(node.fragment, state));
44+
45+
context.state.template.push(
46+
b.stmt(
47+
b.call(
48+
'$.element',
49+
b.id('$$payload'),
50+
tag,
51+
attributes.body.length > 0 && b.thunk(attributes),
52+
children.body.length > 0 && b.thunk(children)
53+
)
54+
)
55+
);
56+
57+
if (context.state.options.dev) {
58+
context.state.template.push(b.stmt(b.call('$.pop_element')));
59+
}
60+
}

0 commit comments

Comments
 (0)