All files / src/internal/server dev.js

97.89% Statements 93/95
87.5% Branches 14/16
100% Functions 5/5
97.89% Lines 93/95

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 87 88 89 90 91 92 93 94 95 961x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 5x 5x 5x 5x 5x 5x 5x 5x 5x 1x 1x 1x 1x 10x 10x 10x 1x 1x 1x 1x 1x 1x 5x 5x 5x 5x 5x 5x 1x 1x 1x 1x 1x 1x 1x 1x 117x 117x 117x 117x     117x 117x 60x 60x 11x 3x 3x 3x 8x 8x 60x 117x 117x 38x 38x 14x 2x 2x 2x 12x 12x 38x 117x 117x 117x 1x 1x 115x 115x  
import {
	disallowed_paragraph_contents,
	interactive_elements,
	is_tag_valid_with_parent
} from '../../constants.js';
import { current_component } from './context.js';
 
/**
 * @typedef {{
 * 	tag: string;
 * 	parent: null | Element;
 *  filename: null | string;
 * }} Element
 */
 
/**
 * @type {Element | null}
 */
let parent = null;
 
/**
 * @param {import('#server').Payload} payload
 * @param {string} message
 */
function error_on_client(payload, message) {
	message =
		`${message}\n\n` +
		'Ensure your components render valid HTML as the browser will try to repair invalid HTML, ' +
		'which may result in content being shifted around and will likely result in a hydration mismatch.';
	// eslint-disable-next-line no-console
	console.error(message);
	payload.head.out += `<script>console.error(\`${message}\`)</script>`;
}
 
/**
 * @param {string | null} file
 */
function print_file(file) {
	return file ? `(${file})` : '';
}
 
/**
 * @param {import('#server').Payload} payload
 * @param {Element} parent
 * @param {Element} child
 */
function print_error(payload, parent, child) {
	error_on_client(
		payload,
		`<${child.tag}> ${print_file(child.filename)} is not a valid child element of <${parent.tag}> ${print_file(parent.filename)}`
	);
}
 
/**
 * @param {import('#server').Payload} payload
 * @param {string} tag
 * @param {number} line
 * @param {number} column
 */
export function push_element(payload, tag, line, column) {
	var filename = /** @type {import('#server').Component} */ (current_component).function.filename;
	var child = { tag, parent, filename };
 
	if (parent !== null && !is_tag_valid_with_parent(tag, parent.tag)) {
		print_error(payload, parent, child);
	}
 
	if (interactive_elements.has(tag)) {
		let element = parent;
		while (element !== null) {
			if (interactive_elements.has(element.tag)) {
				print_error(payload, element, child);
				break;
			}
			element = element.parent;
		}
	}
 
	if (disallowed_paragraph_contents.includes(tag)) {
		let element = parent;
		while (element !== null) {
			if (element.tag === 'p') {
				print_error(payload, element, child);
				break;
			}
			element = element.parent;
		}
	}
 
	parent = child;
}
 
export function pop_element() {
	parent = /** @type {Element} */ (parent).parent;
}