All files / src/internal/server dev.js

100% Statements 85/85
90.9% Branches 10/11
100% Functions 4/4
100% Lines 85/85

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 861x 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 16x 16x 16x 16x 1x 1x 1x 1x 1x 1x 8x 8x 8x 8x 8x 8x 5x 5x 5x 5x 5x 5x 1x 1x 1x 1x 1x 1x 1x 1x 151x 151x 151x 151x 29x 29x 29x 29x 6x 6x 29x 29x 10x 10x 2x 2x 10x 10x 29x 151x 151x 151x 1x 1x 149x 149x  
/** @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 };
 
	if (parent !== null) {
		var ancestor = parent.parent;
		var ancestors = [parent.tag];
 
		if (!is_tag_valid_with_parent(tag, parent.tag)) {
			print_error(payload, parent, child);
		}
 
		while (ancestor != null) {
			ancestors.push(ancestor.tag);
			if (!is_tag_valid_with_ancestor(tag, ancestors)) {
				print_error(payload, ancestor, child);
			}
			ancestor = ancestor.parent;
		}
	}
 
	parent = child;
}
 
export function pop_element() {
	parent = /** @type {Element} */ (parent).parent;
}