All files / src/internal/client/dom/blocks html.js

100% Statements 90/90
96.29% Branches 26/27
100% Functions 1/1
100% Lines 84/84

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 852x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 96x 96x 96x 96x 96x 96x 96x 96x 162x 162x 162x 64x 64x 64x 162x 162x 160x 160x 160x 46x 46x 46x 46x 46x 94x 46x 50x 50x 50x 46x 46x 2x 2x 2x 44x 44x 44x 44x 44x 114x 114x 160x 100x 114x 114x 114x 114x 114x 114x 160x 15x 15x 114x 114x 114x 114x 114x 114x 160x 15x 19x 19x 160x 99x 99x 160x 96x 96x  
/** @import { Effect, TemplateNode } from '#client' */
import { HYDRATION_ERROR } from '../../../../constants.js';
import { block, branch, destroy_effect } from '../../reactivity/effects.js';
import { hydrate_next, hydrate_node, hydrating, set_hydrate_node } from '../hydration.js';
import { create_fragment_from_html } from '../reconciler.js';
import { assign_nodes } from '../template.js';
import * as w from '../../warnings.js';
 
/**
 * @param {Element | Text | Comment} node
 * @param {() => string} get_value
 * @param {boolean} svg
 * @param {boolean} mathml
 * @returns {void}
 */
export function html(node, get_value, svg, mathml) {
	var anchor = node;
 
	var value = '';
 
	/** @type {Effect | null} */
	var effect;
 
	block(() => {
		if (value === (value = get_value())) return;
 
		if (effect) {
			destroy_effect(effect);
			effect = null;
		}
 
		if (value === '') return;
 
		effect = branch(() => {
			if (hydrating) {
				var next = hydrate_next();
				var last = next;
 
				while (
					next !== null &&
					(next.nodeType !== 8 || /** @type {Comment} */ (next).data !== '')
				) {
					last = next;
					next = /** @type {TemplateNode} */ (next.nextSibling);
				}
 
				if (next === null) {
					w.hydration_mismatch();
					throw HYDRATION_ERROR;
				}
 
				assign_nodes(hydrate_node, last);
				anchor = set_hydrate_node(next);
				return;
			}
 
			var html = value + '';
			if (svg) html = `<svg>${html}</svg>`;
			else if (mathml) html = `<math>${html}</math>`;
 
			// Don't use create_fragment_with_script_from_html here because that would mean script tags are executed.
			// @html is basically `.innerHTML = ...` and that doesn't execute scripts either due to security reasons.
			/** @type {DocumentFragment | Element} */
			var node = create_fragment_from_html(html);
 
			if (svg || mathml) {
				node = /** @type {Element} */ (node.firstChild);
			}
 
			assign_nodes(
				/** @type {TemplateNode} */ (node.firstChild),
				/** @type {TemplateNode} */ (node.lastChild)
			);
 
			if (svg || mathml) {
				while (node.firstChild) {
					anchor.before(node.firstChild);
				}
			} else {
				anchor.before(node);
			}
		});
	});
}