All files / src/internal/client/dom/blocks css-props.js

91.42% Statements 64/70
71.42% Branches 5/7
100% Functions 1/1
90.9% Lines 60/66

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 672x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x     1x 1x 1x 1x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x         2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x  
import { namespace_svg } from '../../../../constants.js';
import { hydrate_anchor, hydrating } from '../hydration.js';
import { empty } from '../operations.js';
import { render_effect } from '../../reactivity/effects.js';
 
/**
 * @param {HTMLElement | SVGElement | Comment} node
 * @param {boolean} is_html
 * @param {() => Record<string, string>} props
 * @param {(anchor: Element | Text | Comment) => any} component
 * @returns {void}
 */
export function css_props(node, is_html, props, component) {
	/** @type {HTMLElement | SVGElement} */
	let element;
 
	/** @type {Text | Comment} */
	let component_anchor;
 
	if (hydrating) {
		// Hydration: css props element is surrounded by a ssr comment ...
		element = /** @type {HTMLElement | SVGElement} */ (node);
 
		// ... and the child(ren) of the css props element is also surround by a ssr comment
		component_anchor = /** @type {Comment} */ (
			hydrate_anchor(/** @type {Comment} */ (element.firstChild))
		);
	} else {
		if (is_html) {
			element = document.createElement('div');
			element.style.display = 'contents';
		} else {
			element = document.createElementNS(namespace_svg, 'g');
		}
 
		node.before(element); // TODO do we even need an anchor? Can we just pass in the correct element directly from the template?
		component_anchor = element.appendChild(empty());
	}
 
	component(component_anchor);
 
	render_effect(() => {
		/** @type {Record<string, string>} */
		let current_props = {};
 
		render_effect(() => {
			const next_props = props();
 
			for (const key in current_props) {
				if (!(key in next_props)) {
					element.style.removeProperty(key);
				}
			}
 
			for (const key in next_props) {
				element.style.setProperty(key, next_props[key]);
			}
 
			current_props = next_props;
		});
 
		return () => {
			element.remove();
		};
	});
}