All files / src/internal/client/dom hydration.js

89.13% Statements 82/92
81.25% Branches 13/16
100% Functions 6/6
88.88% Lines 80/90

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 912x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 4849x 4849x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 10450x 10450x 2x 2x 7905x       7905x 7905x 2x 2x 2x 7775x 3435x 3435x 3435x 3435x 3435x 3x 3435x       3435x 3435x 7775x 2x 2x 501x 222x 222x 501x 2x 2x 2x 2x 2x 444x 444x 444x 444x 459x 444x 444x 444x 444x         444x 15x 15x 15x 15x 15x 444x  
/** @import { TemplateNode } from '#client' */
 
import {
	HYDRATION_END,
	HYDRATION_ERROR,
	HYDRATION_START,
	HYDRATION_START_ELSE
} from '../../../constants.js';
import * as w from '../warnings.js';
 
/**
 * Use this variable to guard everything related to hydration code so it can be treeshaken out
 * if the user doesn't use the `hydrate` method and these code paths are therefore not needed.
 */
export let hydrating = false;
 
/** @param {boolean} value */
export function set_hydrating(value) {
	hydrating = value;
}
 
/**
 * The node that is currently being hydrated. This starts out as the first node inside the opening
 * <!--[--> comment, and updates each time a component calls `$.child(...)` or `$.sibling(...)`.
 * When entering a block (e.g. `{#if ...}`), `hydrate_node` is the block opening comment; by the
 * time we leave the block it is the closing comment, which serves as the block's anchor.
 * @type {TemplateNode}
 */
export let hydrate_node;
 
/** @param {TemplateNode} node */
export function set_hydrate_node(node) {
	return (hydrate_node = node);
}
 
export function hydrate_next() {
	if (hydrate_node === null) {
		w.hydration_mismatch();
		throw HYDRATION_ERROR;
	}
	return (hydrate_node = /** @type {TemplateNode} */ (hydrate_node.nextSibling));
}
 
/** @param {TemplateNode} node */
export function reset(node) {
	if (hydrating) {
		// If we are resetting back to a parent, then we should be at the end of the current parent
		// and thus have no more siblings to hydrate (except if we're inside a template).
		if (
			hydrate_node !== null &&
			hydrate_node.nextSibling !== null &&
			hydrate_node.nodeName !== 'TEMPLATE'
		) {
			w.hydration_mismatch();
			throw HYDRATION_ERROR;
		}
		hydrate_node = node;
	}
}
 
export function next() {
	if (hydrating) {
		hydrate_next();
	}
}
 
/**
 * Removes all nodes starting at `hydrate_node` up until the next hydration end comment
 */
export function remove_nodes() {
	var depth = 0;
	var node = hydrate_node;
 
	while (true) {
		if (node.nodeType === 8) {
			var data = /** @type {Comment} */ (node).data;
 
			if (data === HYDRATION_END) {
				if (depth === 0) return node;
				depth -= 1;
			} else if (data === HYDRATION_START || data === HYDRATION_START_ELSE) {
				depth += 1;
			}
		}
 
		var next = /** @type {TemplateNode} */ (node.nextSibling);
		node.remove();
		node = next;
	}
}