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

100% Statements 63/63
100% Branches 9/9
100% Functions 2/2
100% Lines 58/58

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 592x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1527x 1527x 2x 2x 2x 2x 2x 2x 38x 38x 38x 38x 38x 38x 38x 38x 38x 18x 18x 18x 18x 16x 16x 18x 18x 18x 20x 18x 2x 2x 18x 18x 38x 20x 20x 38x 38x 38x 38x 38x 18x 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) {
			head_anchor = hydrate_node; // so that next head block starts from the correct node
			set_hydrate_node(/** @type {TemplateNode} */ (previous_hydrate_node));
		}
	}
}