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

100% Statements 89/89
100% Branches 18/18
100% Functions 3/3
100% Lines 86/86

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 872x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 4455x 4455x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1482x 1482x 1482x 2x 2x 2x 2x 2x 2x 2x 2x 2x 12769x 6113x 6113x 6656x 6656x 6656x 6656x 12769x 5x 5x 6651x 6651x 6651x 6651x 6651x 12769x 40062x 26814x 26814x 26814x 10082x 26814x 16731x 6649x 6649x 6649x 10082x 10082x 10082x 26814x 33413x 33413x 33413x 33413x 2x 2x 2x 2x 2x 2x 2x 1x 1x 2x 2x 2x 2x 2x  
import { DEV } from 'esm-env';
import { HYDRATION_END, HYDRATION_START, HYDRATION_ERROR } 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;
}
 
/** @type {import('#client').TemplateNode} */
export let hydrate_start = /** @type {any} */ (null);
 
/** @type {import('#client').TemplateNode} */
export let hydrate_end = /** @type {any} */ (null);
 
/**
 * @param {import('#client').TemplateNode} start
 * @param {import('#client').TemplateNode} end
 */
export function set_hydrate_nodes(start, end) {
	hydrate_start = start;
	hydrate_end = end;
}
 
/**
 * This function is only called when `hydrating` is true. If passed a `<!--[-->` opening
 * hydration marker, it finds the corresponding closing marker and sets `hydrate_start`
 * and `hydrate_end` to the content inside, before returning the closing marker.
 * @param {Node} node
 * @returns {Node}
 */
export function hydrate_anchor(node) {
	if (node.nodeType !== 8) {
		return node;
	}
 
	var current = /** @type {Node | null} */ (node);
 
	// TODO this could have false positives, if a user comment consisted of `[`. need to tighten that up
	if (/** @type {Comment} */ (current).data !== HYDRATION_START) {
		return node;
	}
 
	/** @type {import('#client').TemplateNode} */
	var start = /** @type {any} */ (null);
	var depth = 0;
 
	while ((current = /** @type {Node} */ (current).nextSibling) !== null) {
		if (current.nodeType === 8) {
			var data = /** @type {Comment} */ (current).data;
 
			if (data === HYDRATION_START) {
				depth += 1;
			} else if (data[0] === HYDRATION_END) {
				if (depth === 0) {
					hydrate_start = start;
					return current;
				}
 
				depth -= 1;
			}
		}
 
		start ??= /** @type {import('#client').TemplateNode} */ (current);
		hydrate_end = /** @type {import('#client').TemplateNode} */ (current);
	}
 
	let location;
 
	if (DEV) {
		// @ts-expect-error
		const loc = node.parentNode?.__svelte_meta?.loc;
		if (loc) {
			location = `${loc.file}:${loc.line}:${loc.column}`;
		}
	}
 
	w.hydration_mismatch(location);
	throw HYDRATION_ERROR;
}