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

98.5% Statements 66/67
84.61% Branches 11/13
100% Functions 4/4
98.46% Lines 64/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 10x 10x 10x 10x 10x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 16x 16x 16x 6x 16x 2x 2x 2x   2x 2x 2x 2x 2x 6x 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]));
}