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

96.66% Statements 58/60
87.5% Branches 7/8
100% Functions 2/2
96.42% Lines 54/56

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 572x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1425x 1425x 2x 2x 2x 2x 2x 2x 38x 38x 38x 38x 38x 38x 38x 38x 38x 18x 18x 18x 18x 16x 16x 18x 18x 18x 18x 18x     18x 18x 18x 38x 20x 20x 38x 38x 38x 38x 38x 18x 18x 38x 38x  
import { hydrate_anchor, hydrate_nodes, hydrating, set_hydrate_nodes } from '../hydration.js';
import { empty } from '../operations.js';
import { block } from '../../reactivity/effects.js';
import { HYDRATION_END, HYDRATION_START } from '../../../../constants.js';
 
/**
 * @type {Node | undefined}
 */
let head_anchor;
 
export function reset_head_anchor() {
	head_anchor = undefined;
}
 
/**
 * @param {(anchor: Node) => import('#client').Dom | 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_nodes = null;
	let was_hydrating = hydrating;
 
	/** @type {Comment | Text} */
	var anchor;
 
	if (hydrating) {
		previous_hydrate_nodes = hydrate_nodes;
 
		// 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 {import('#client').TemplateNode} */ (document.head.firstChild);
		}
 
		while (
			head_anchor.nodeType !== 8 ||
			/** @type {Comment} */ (head_anchor).data !== HYDRATION_START
		) {
			head_anchor = /** @type {import('#client').TemplateNode} */ (head_anchor.nextSibling);
		}
 
		head_anchor = /** @type {import('#client').TemplateNode} */ (hydrate_anchor(head_anchor));
		head_anchor = /** @type {import('#client').TemplateNode} */ (head_anchor.nextSibling);
	} else {
		anchor = document.head.appendChild(empty());
	}
 
	try {
		block(() => render_fn(anchor));
	} finally {
		if (was_hydrating) {
			set_hydrate_nodes(/** @type {import('#client').TemplateNode[]} */ (previous_hydrate_nodes));
		}
	}
}