pull/12215/head
Rich Harris 2 months ago
parent 239ccd5666
commit aa553ef125

@ -36,6 +36,7 @@ import {
EACH_KEYED,
is_capture_event,
TEMPLATE_FRAGMENT,
TEMPLATE_UNSET_START,
TEMPLATE_USE_IMPORT_NODE,
TRANSITION_GLOBAL,
TRANSITION_IN,
@ -1680,18 +1681,32 @@ export const template_visitors = {
process_children(trimmed, expression, false, { ...context, state });
let flags = TEMPLATE_FRAGMENT;
if (state.metadata.context.template_needs_import_node) {
flags |= TEMPLATE_USE_IMPORT_NODE;
}
if (trimmed[0].type === 'Component') {
flags |= TEMPLATE_UNSET_START;
}
if (trimmed[0].type === 'RenderTag') {
const callee = unwrap_optional(trimmed[0].expression).callee;
const is_reactive =
callee.type !== 'Identifier' || context.state.scope.get(callee.name)?.kind !== 'normal';
if (!is_reactive) {
flags |= TEMPLATE_UNSET_START;
}
}
const use_comment_template = state.template.length === 1 && state.template[0] === '<!>';
if (use_comment_template) {
// special case — we can use `$.comment` instead of creating a unique template
body.push(b.var(id, b.call('$.comment')));
body.push(b.var(id, b.call('$.comment', flags !== 0 && b.literal(flags))));
} else {
let flags = TEMPLATE_FRAGMENT;
if (state.metadata.context.template_needs_import_node) {
flags |= TEMPLATE_USE_IMPORT_NODE;
}
add_template(template_name, [
b.template([b.quasi(state.template.join(''), true)], []),
b.literal(flags)

@ -18,6 +18,7 @@ export const TRANSITION_GLOBAL = 1 << 2;
export const TEMPLATE_FRAGMENT = 1;
export const TEMPLATE_USE_IMPORT_NODE = 1 << 1;
export const TEMPLATE_UNSET_START = 1 << 2;
export const HYDRATION_START = '[';
export const HYDRATION_END = ']';

@ -2,7 +2,11 @@ import { hydrate_nodes, hydrate_start, hydrating } from './hydration.js';
import { empty } from './operations.js';
import { create_fragment_from_html } from './reconciler.js';
import { current_effect } from '../runtime.js';
import { TEMPLATE_FRAGMENT, TEMPLATE_USE_IMPORT_NODE } from '../../../constants.js';
import {
TEMPLATE_FRAGMENT,
TEMPLATE_UNSET_START,
TEMPLATE_USE_IMPORT_NODE
} from '../../../constants.js';
import { is_array } from '../utils.js';
import { queue_micro_task } from './task.js';
@ -34,7 +38,7 @@ export function push_template_node(
/**
*
* @param {import('#client').TemplateNode | null} start
* @param {import('#client').TemplateNode | null | undefined} start
* @param {import('#client').TemplateNode} end
*/
function assign_nodes(start, end) {
@ -43,7 +47,9 @@ function assign_nodes(start, end) {
if (effect.nodes === null) {
effect.nodes = { start, end };
} else {
effect.nodes.end = end;
if (effect.nodes.start === undefined) {
effect.nodes.start = start;
}
}
}
@ -61,10 +67,14 @@ export function template(content, flags) {
var node;
var has_start = !content.startsWith('<!>');
var unset = (flags & TEMPLATE_UNSET_START) !== 0;
return () => {
if (hydrating) {
assign_nodes(has_start ? hydrate_nodes[0] : null, hydrate_nodes[hydrate_nodes.length - 1]);
assign_nodes(
has_start ? hydrate_nodes[0] : unset ? undefined : null,
hydrate_nodes[hydrate_nodes.length - 1]
);
push_template_node(is_fragment ? hydrate_nodes : hydrate_start);
return hydrate_start;
@ -80,7 +90,9 @@ export function template(content, flags) {
var start = is_fragment
? has_start
? /** @type {import('#client').TemplateNode} */ (clone.firstChild)
: null
: unset
? undefined
: null
: /** @type {import('#client').TemplateNode} */ (clone);
var end = /** @type {import('#client').TemplateNode} */ (is_fragment ? clone.lastChild : clone);
@ -146,8 +158,8 @@ export function ns_template(content, flags, ns = 'svg') {
}
if (!node) {
var fragment = /** @type {Element} */ (create_fragment_from_html(wrapped));
var root = fragment.firstChild;
var fragment = /** @type {DocumentFragment} */ (create_fragment_from_html(wrapped));
var root = /** @type {Element} */ (fragment.firstChild);
if (is_fragment) {
node = document.createDocumentFragment();
@ -271,9 +283,17 @@ export function text(anchor) {
return node;
}
export function comment() {
/**
* @param {number} [flags]
*/
export function comment(flags = 0) {
// we're not delegating to `template` here for performance reasons
if (hydrating) {
assign_nodes(
(flags & TEMPLATE_UNSET_START) !== 0 ? undefined : null,
hydrate_nodes[hydrate_nodes.length - 1]
);
push_template_node(hydrate_nodes);
return hydrate_start;
}
@ -281,6 +301,8 @@ export function comment() {
var frag = document.createDocumentFragment();
var anchor = empty();
frag.append(anchor);
assign_nodes((flags & TEMPLATE_UNSET_START) !== 0 ? undefined : null, anchor);
push_template_node([anchor]);
return frag;

@ -71,6 +71,8 @@ export function push_effect(effect, parent_effect) {
}
}
var uid = 1;
/**
* @param {number} type
* @param {null | (() => void | (() => void))} fn
@ -82,6 +84,7 @@ function create_effect(type, fn, sync) {
/** @type {import('#client').Effect} */
var effect = {
id: uid++,
ctx: current_component_context,
deps: null,
dom: null,
@ -388,13 +391,18 @@ export function destroy_effect(effect, remove_dom = true) {
*/
function get_first_node(effect) {
if (effect.nodes !== null) {
if (effect.nodes.start !== null) {
if (effect.nodes.start != null) {
return effect.nodes.start;
}
}
if (effect.first !== null) {
return get_first_node(effect.first);
var child = effect.first;
while (child && (child.f & (BLOCK_EFFECT | BRANCH_EFFECT)) === 0) {
child = child.next;
}
if (child !== null) {
return get_first_node(child);
}
return null;

@ -37,7 +37,7 @@ export interface Derived<V = unknown> extends Value<V>, Reaction {
export interface Effect extends Reaction {
parent: Effect | null;
dom: Dom | null;
nodes: null | { start: null | TemplateNode; end: TemplateNode };
nodes: null | { start: undefined | null | TemplateNode; end: TemplateNode };
/** The associated component context */
ctx: null | ComponentContext;
/** The effect function */

@ -6,7 +6,7 @@ export default defineConfig({
build: {
minify: false
},
plugins: [inspect(), svelte()],
plugins: [inspect(), svelte({ compilerOptions: { hmr: false }})],
optimizeDeps: {
// svelte is a local workspace package, optimizing it would require dev server restarts with --force for every change
exclude: ['svelte']

Loading…
Cancel
Save