All files / src/internal/client/dom/blocks svelte-head.js

100% Statements 62/62
100% Branches 9/9
100% Functions 2/2
100% Lines 57/57

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 582x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1521x 1521x 2x 2x 2x 2x 2x 2x 38x 38x 38x 38x 38x 38x 38x 38x 38x 18x 18x 18x 18x 16x 16x 18x 18x 18x 25x 18x 15x 15x 18x 18x 38x 20x 20x 38x 38x 38x 38x 38x 18x 18x 38x 38x  
/** @import { TemplateNode } from '#client' */
import { hydrate_node, hydrating, set_hydrate_node } from '../hydration.js';
import { empty } from '../operations.js';
import { block } from '../../reactivity/effects.js';
import { HEAD_EFFECT } from '../../constants.js';
import { HYDRATION_START } from '../../../../constants.js';
 
/**
 * @type {Node | undefined}
 */
let head_anchor;
 
export function reset_head_anchor() {
	head_anchor = undefined;
}
 
/**
 * @param {(anchor: Node) => void} render_fn
 * @returns {void}
 */
export function head(render_fn) {
	// The head function may be called after the first hydration pass and ssr comment nodes may still be present,
	// therefore we need to skip that when we detect that we're not in hydration mode.
	let previous_hydrate_node = null;
	let was_hydrating = hydrating;
 
	/** @type {Comment | Text} */
	var anchor;
 
	if (hydrating) {
		previous_hydrate_node = hydrate_node;
 
		// There might be multiple head blocks in our app, so we need to account for each one needing independent hydration.
		if (head_anchor === undefined) {
			head_anchor = /** @type {TemplateNode} */ (document.head.firstChild);
		}
 
		while (
			head_anchor.nodeType !== 8 ||
			/** @type {Comment} */ (head_anchor).data !== HYDRATION_START
		) {
			head_anchor = /** @type {TemplateNode} */ (head_anchor.nextSibling);
		}
 
		head_anchor = set_hydrate_node(/** @type {TemplateNode} */ (head_anchor.nextSibling));
	} else {
		anchor = document.head.appendChild(empty());
	}
 
	try {
		block(() => render_fn(anchor), HEAD_EFFECT);
	} finally {
		if (was_hydrating) {
			set_hydrate_node(/** @type {TemplateNode} */ (previous_hydrate_node));
		}
	}
}