svelte
Version:
Cybernetically enhanced web apps
71 lines (58 loc) • 1.8 kB
JavaScript
/** @import { TemplateNode } from '#client' */
import { EFFECT_TRANSPARENT } from '#client/constants';
import {
hydrate_next,
hydrating,
read_hydration_instruction,
skip_nodes,
set_hydrate_node,
set_hydrating
} from '../hydration.js';
import { block } from '../../reactivity/effects.js';
import { HYDRATION_START_ELSE } from '../../../../constants.js';
import { BranchManager } from './branches.js';
// TODO reinstate https://github.com/sveltejs/svelte/pull/15250
/**
* @param {TemplateNode} node
* @param {(branch: (fn: (anchor: Node) => void, flag?: boolean) => void) => void} fn
* @param {boolean} [elseif] True if this is an `{:else if ...}` block rather than an `{#if ...}`, as that affects which transitions are considered 'local'
* @returns {void}
*/
export function if_block(node, fn, elseif = false) {
if (hydrating) {
hydrate_next();
}
var branches = new BranchManager(node);
var flags = elseif ? EFFECT_TRANSPARENT : 0;
/**
* @param {boolean} condition,
* @param {null | ((anchor: Node) => void)} fn
*/
function update_branch(condition, fn) {
if (hydrating) {
const is_else = read_hydration_instruction(node) === HYDRATION_START_ELSE;
if (condition === is_else) {
// Hydration mismatch: remove everything inside the anchor and start fresh.
// This could happen with `{#if browser}...{/if}`, for example
var anchor = skip_nodes();
set_hydrate_node(anchor);
branches.anchor = anchor;
set_hydrating(false);
branches.ensure(condition, fn);
set_hydrating(true);
return;
}
}
branches.ensure(condition, fn);
}
block(() => {
var has_branch = false;
fn((fn, flag = true) => {
has_branch = true;
update_branch(flag, fn);
});
if (!has_branch) {
update_branch(false, null);
}
}, flags);
}