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

100% Statements 92/92
96.29% Branches 26/27
100% Functions 1/1
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 2x 2x 2x 2x 96x 96x 96x 96x 96x 96x 96x 96x 162x 162x 162x 64x 64x 64x 162x 162x 160x 160x 160x 47x 47x 47x 47x 47x 47x 47x 98x 47x 52x 52x 52x 47x 47x 1x 1x 1x 46x 46x 46x 46x 46x 113x 113x 160x 99x 113x 113x 113x 113x 113x 113x 160x 15x 15x 113x 113x 113x 113x 113x 113x 160x 15x 19x 19x 160x 98x 98x 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) {
				// We're deliberately not trying to repair mismatches between server and client,
				// as it's costly and error-prone (and it's an edge case to have a mismatch anyway)
				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);
			}
		});
	});
}