All files / src/internal/server dev.js

100% Statements 80/80
92.3% Branches 12/13
100% Functions 4/4
100% Lines 80/80

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 811x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 18x 18x 18x 18x 1x 1x 1x 1x 1x 1x 9x 9x 9x 9x 9x 9x 4x 4x 4x 4x 4x 4x 1x 1x 1x 1x 1x 1x 1x 1x 147x 147x 147x 147x 147x 7x 7x 147x 147x 10x 2x 2x 10x 10x 147x 147x 147x 1x 1x 145x 145x  
/** @import { Component, Payload } from '#server' */
import { FILENAME } from '../../constants.js';
import {
	is_tag_valid_with_ancestor,
	is_tag_valid_with_parent
} from '../../html-tree-validation.js';
import { current_component } from './context.js';
 
/**
 * @typedef {{
 * 	tag: string;
 * 	parent: null | Element;
 *  filename: null | string;
 *  line: number;
 *  column: number;
 * }} Element
 */
 
/**
 * @type {Element | null}
 */
let parent = null;
 
/** @type {Set<string>} */
let seen;
 
/**
 * @param {Element} element
 */
function stringify(element) {
	if (element.filename === null) return `\`<${element.tag}>\``;
	return `\`<${element.tag}>\` (${element.filename}:${element.line}:${element.column})`;
}
 
/**
 * @param {Payload} payload
 * @param {Element} parent
 * @param {Element} child
 */
function print_error(payload, parent, child) {
	var message =
		`node_invalid_placement_ssr: ${stringify(parent)} cannot contain ${stringify(child)}\n\n` +
		'This can cause content to shift around as the browser repairs the HTML, and will likely result in a `hydration_mismatch` warning.';
 
	if ((seen ??= new Set()).has(message)) return;
	seen.add(message);
 
	// eslint-disable-next-line no-console
	console.error(message);
	payload.head.out += `<script>console.error(${JSON.stringify(message)})</script>`;
}
 
/**
 * @param {Payload} payload
 * @param {string} tag
 * @param {number} line
 * @param {number} column
 */
export function push_element(payload, tag, line, column) {
	var filename = /** @type {Component} */ (current_component).function[FILENAME];
	var child = { tag, parent, filename, line, column };
	var ancestor = parent?.parent;
 
	if (parent !== null && !is_tag_valid_with_parent(tag, parent.tag)) {
		print_error(payload, parent, child);
	}
 
	while (ancestor != null) {
		if (!is_tag_valid_with_ancestor(tag, ancestor.tag)) {
			print_error(payload, ancestor, child);
		}
		ancestor = ancestor.parent;
	}
 
	parent = child;
}
 
export function pop_element() {
	parent = /** @type {Element} */ (parent).parent;
}