|
|
@ -9,16 +9,16 @@ import {
|
|
|
|
set_hydrating
|
|
|
|
set_hydrating
|
|
|
|
} from '../hydration.js';
|
|
|
|
} from '../hydration.js';
|
|
|
|
import { block, branch, pause_effect, resume_effect } from '../../reactivity/effects.js';
|
|
|
|
import { block, branch, pause_effect, resume_effect } from '../../reactivity/effects.js';
|
|
|
|
import { HYDRATION_START_ELSE, UNINITIALIZED } from '../../../../constants.js';
|
|
|
|
import { HYDRATION_START, HYDRATION_START_ELSE, UNINITIALIZED } from '../../../../constants.js';
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @param {TemplateNode} node
|
|
|
|
* @param {TemplateNode} node
|
|
|
|
* @param {(branch: (fn: (anchor: Node) => void, flag?: boolean) => void) => void} fn
|
|
|
|
* @param {(branch: (fn: (anchor: Node, elseif?: [number,number]) => 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'
|
|
|
|
* @param {[number,number]} [elseif]
|
|
|
|
* @returns {void}
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
export function if_block(node, fn, elseif = false) {
|
|
|
|
export function if_block(node, fn, [root_index, hydrate_index] = [0, 0]) {
|
|
|
|
if (hydrating) {
|
|
|
|
if (hydrating && root_index === 0) {
|
|
|
|
hydrate_next();
|
|
|
|
hydrate_next();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -33,26 +33,44 @@ export function if_block(node, fn, elseif = false) {
|
|
|
|
/** @type {UNINITIALIZED | boolean | null} */
|
|
|
|
/** @type {UNINITIALIZED | boolean | null} */
|
|
|
|
var condition = UNINITIALIZED;
|
|
|
|
var condition = UNINITIALIZED;
|
|
|
|
|
|
|
|
|
|
|
|
var flags = elseif ? EFFECT_TRANSPARENT : 0;
|
|
|
|
var flags = root_index > 0 ? EFFECT_TRANSPARENT : 0;
|
|
|
|
|
|
|
|
|
|
|
|
var has_branch = false;
|
|
|
|
var has_branch = false;
|
|
|
|
|
|
|
|
|
|
|
|
const set_branch = (/** @type {(anchor: Node) => void} */ fn, flag = true) => {
|
|
|
|
const set_branch = (
|
|
|
|
|
|
|
|
/** @type {(anchor: Node, elseif?: [number,number]) => void} */ fn,
|
|
|
|
|
|
|
|
flag = true
|
|
|
|
|
|
|
|
) => {
|
|
|
|
has_branch = true;
|
|
|
|
has_branch = true;
|
|
|
|
update_branch(flag, fn);
|
|
|
|
update_branch(flag, fn);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const update_branch = (
|
|
|
|
const update_branch = (
|
|
|
|
/** @type {boolean | null} */ new_condition,
|
|
|
|
/** @type {boolean | null} */ new_condition,
|
|
|
|
/** @type {null | ((anchor: Node) => void)} */ fn
|
|
|
|
/** @type {null | ((anchor: Node, elseif?: [number,number]) => void)} */ fn
|
|
|
|
) => {
|
|
|
|
) => {
|
|
|
|
if (condition === (condition = new_condition)) return;
|
|
|
|
if (condition === (condition = new_condition)) return;
|
|
|
|
|
|
|
|
|
|
|
|
/** Whether or not there was a hydration mismatch. Needs to be a `let` or else it isn't treeshaken out */
|
|
|
|
/** Whether or not there was a hydration mismatch. Needs to be a `let` or else it isn't treeshaken out */
|
|
|
|
let mismatch = false;
|
|
|
|
let mismatch = false;
|
|
|
|
|
|
|
|
|
|
|
|
if (hydrating) {
|
|
|
|
if (hydrating && hydrate_index !== -1) {
|
|
|
|
const is_else = /** @type {Comment} */ (anchor).data === HYDRATION_START_ELSE;
|
|
|
|
if (root_index === 0) {
|
|
|
|
|
|
|
|
const data = /** @type {Comment} */ (anchor).data;
|
|
|
|
|
|
|
|
if (data === HYDRATION_START) {
|
|
|
|
|
|
|
|
hydrate_index = 0;
|
|
|
|
|
|
|
|
} else if (data === HYDRATION_START_ELSE) {
|
|
|
|
|
|
|
|
hydrate_index = Infinity;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
hydrate_index = parseInt(data.substring(1));
|
|
|
|
|
|
|
|
if (hydrate_index !== hydrate_index) {
|
|
|
|
|
|
|
|
// if hydrate_index is NaN
|
|
|
|
|
|
|
|
// we set an invalid index to force mismatch
|
|
|
|
|
|
|
|
hydrate_index = condition ? Infinity : -1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const is_else = hydrate_index > root_index;
|
|
|
|
|
|
|
|
|
|
|
|
if (!!condition === is_else) {
|
|
|
|
if (!!condition === is_else) {
|
|
|
|
// Hydration mismatch: remove everything inside the anchor and start fresh.
|
|
|
|
// Hydration mismatch: remove everything inside the anchor and start fresh.
|
|
|
@ -62,6 +80,7 @@ export function if_block(node, fn, elseif = false) {
|
|
|
|
set_hydrate_node(anchor);
|
|
|
|
set_hydrate_node(anchor);
|
|
|
|
set_hydrating(false);
|
|
|
|
set_hydrating(false);
|
|
|
|
mismatch = true;
|
|
|
|
mismatch = true;
|
|
|
|
|
|
|
|
hydrate_index = -1; // ignore hydration in next else if
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -81,7 +100,7 @@ export function if_block(node, fn, elseif = false) {
|
|
|
|
if (alternate_effect) {
|
|
|
|
if (alternate_effect) {
|
|
|
|
resume_effect(alternate_effect);
|
|
|
|
resume_effect(alternate_effect);
|
|
|
|
} else if (fn) {
|
|
|
|
} else if (fn) {
|
|
|
|
alternate_effect = branch(() => fn(anchor));
|
|
|
|
alternate_effect = branch(() => fn(anchor, [root_index + 1, hydrate_index]));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (consequent_effect) {
|
|
|
|
if (consequent_effect) {
|
|
|
|