pull/14551/head
adiguba 2 years ago
parent 47918328d7
commit a23bbaf24c

@ -3,6 +3,7 @@
/** @import { ComponentContext } from '../types' */
import * as b from '../../../../utils/builders.js';
/**
* @param {AST.IfBlock} node
* @param {ComponentContext} context
@ -10,6 +11,46 @@ import * as b from '../../../../utils/builders.js';
export function IfBlock(node, context) {
context.state.template.push_quasi('<!>');
// const conditions = [ ]
/** @type {AST.IfBlock} */
let if_block = node;
/** @type {Expression[]} */
const args = [context.state.node];
while (true) {
const expression = /** @type {Expression} */ (context.visit(if_block.test));
const consequent = /** @type {BlockStatement} */ (context.visit(if_block.consequent));
args.push(b.array([
b.thunk(expression),
b.arrow([b.id('$$anchor')], consequent)]) );
const alternate = if_block.alternate;
if (alternate && alternate.nodes.length === 1 && alternate.nodes[0].type === 'IfBlock' && alternate.nodes[0].elseif) {
if_block = alternate.nodes[0];
} else {
break;
}
}
if (if_block.alternate) {
const alternate = /** @type {BlockStatement} */ (context.visit(if_block.alternate));
args.push(b.array([
b.arrow([], b.true),
b.arrow([b.id('$$anchor')], alternate)
]));
}
context.state.init.push(b.stmt(b.call('$.if', ...args)));
}
/**
* @param {AST.IfBlock} node
* @param {ComponentContext} context
*/
export function IfBlockOLD(node, context) {
context.state.template.push_quasi('<!>');
const consequent = /** @type {BlockStatement} */ (context.visit(node.consequent));
const args = [

@ -10,6 +10,90 @@ import {
} from '../hydration.js';
import { block, branch, pause_effect, resume_effect } from '../../reactivity/effects.js';
import { HYDRATION_START_ELSE } from '../../../../constants.js';
import { noop } from '../../../shared/utils.js';
/**
* @param {TemplateNode} node
* @param {[() => boolean, (anchor: Node) => void, Effect?][]} conditions
* @returns {void}
*/
export function if_block(node, ...conditions) {
if (hydrating) {
hydrate_next();
}
var anchor = node;
/** @type {Effect | null | undefined} */
var current_effect = null;
/** @type {number | null} */
var current_index = null;
block(() => {
const previous_index = current_index;
const previous_effect = current_effect;
if (current_index === (current_index = conditions.findIndex(c => c[0]()))) return;
/** Whether or not there was a hydration mismatch. Needs to be a `let` or else it isn't treeshaken out */
let mismatch = false;
if (hydrating) {
// TODO
const is_else = -5; // /** @type {Comment} */ (anchor).data === HYDRATION_START_ELSE;
if (current_index !== is_else) {
// Hydration mismatch: remove everything inside the anchor and start fresh.
// This could happen with `{#if browser}...{/if}`, for example
anchor = remove_nodes();
set_hydrate_node(anchor);
set_hydrating(false);
mismatch = true;
}
}
if (current_index < 0) {
current_effect = null;
} else {
current_effect = conditions[current_index][2];
if (current_effect) {
resume_effect(current_effect);
} else {
const fn = conditions[current_index]?.[1];
if (fn) {
let target_anchor = anchor;
if (previous_index != null
&& previous_index > current_index
&& previous_effect && previous_effect.nodes_start) {
target_anchor = previous_effect.nodes_start;
}
current_effect = branch(() => fn(target_anchor));
}
}
}
if (previous_effect && previous_index!=null) {
if (previous_effect.transitions) {
conditions[previous_index][2] = previous_effect;
}
pause_effect(previous_effect, () => {
delete conditions[previous_index][2];
});
}
if (mismatch) {
// continue in hydration mode
set_hydrating(true);
}
});
if (hydrating) {
anchor = hydrate_node;
}
}
/**
* @param {TemplateNode} node
@ -19,7 +103,7 @@ import { HYDRATION_START_ELSE } from '../../../../constants.js';
* @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, get_condition, consequent_fn, alternate_fn = null, elseif = false) {
export function if_block_old(node, get_condition, consequent_fn, alternate_fn = null, elseif = false) {
if (hydrating) {
hydrate_next();
}

Loading…
Cancel
Save