All files / src/internal/client/dom/elements/bindings window.js

97.01% Statements 65/67
83.33% Branches 10/12
100% Functions 4/4
96.92% Lines 63/65

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 662x 2x 2x 2x 2x 2x 2x 2x 2x 2x 6x 6x 6x 21x 21x 21x 21x 21x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 4x 6x 6x 6x 6x 20x 20x 20x 6x 20x 2x 2x 2x   2x 2x 2x 2x 2x 6x 6x 6x 6x 6x 6x   6x 6x 2x 2x 2x 2x 2x 2x 8x 8x  
import { effect, render_effect, teardown } from '../../../reactivity/effects.js';
import { listen } from './shared.js';
 
/**
 * @param {'x' | 'y'} type
 * @param {() => number} get_value
 * @param {(value: number) => void} update
 * @returns {void}
 */
export function bind_window_scroll(type, get_value, update) {
	var is_scrolling_x = type === 'x';
 
	var target_handler = () => {
		scrolling = true;
		clearTimeout(timeout);
		timeout = setTimeout(clear, 100); // TODO use scrollend event if supported (or when supported everywhere?)
 
		update(window[is_scrolling_x ? 'scrollX' : 'scrollY']);
	};
 
	addEventListener('scroll', target_handler, {
		passive: true
	});
 
	var scrolling = false;
 
	/** @type {ReturnType<typeof setTimeout>} */
	var timeout;
	var clear = () => {
		scrolling = false;
	};
	var first = true;
 
	render_effect(() => {
		var latest_value = get_value();
		// Don't scroll to the initial value for accessibility reasons
		if (first) {
			first = false;
		} else if (!scrolling && latest_value != null) {
			scrolling = true;
			clearTimeout(timeout);
			if (is_scrolling_x) {
				scrollTo(latest_value, window.scrollY);
			} else {
				scrollTo(window.scrollX, latest_value);
			}
			timeout = setTimeout(clear, 100);
		}
	});
 
	// Browsers don't fire the scroll event for the initial scroll position when scroll style isn't set to smooth
	effect(target_handler);
 
	teardown(() => {
		removeEventListener('scroll', target_handler);
	});
}
 
/**
 * @param {'innerWidth' | 'innerHeight' | 'outerWidth' | 'outerHeight'} type
 * @param {(size: number) => void} update
 */
export function bind_window_size(type, update) {
	listen(window, ['resize'], () => update(window[type]));
}