import { tick } from 'svelte'; import type { ActionReturn } from 'svelte/action'; interface Attributes { 'on:image-error'?: (e: CustomEvent) => void; 'on:image-load'?: (e: CustomEvent) => void; } export function imageLoad(img: HTMLImageElement): ActionReturn { const onImageError = () => img.dispatchEvent(new CustomEvent('image-error')); const onImageLoaded = () => img.dispatchEvent(new CustomEvent('image-load')); if (img.complete) { // Browser has fetched the image, naturalHeight is used to check // if any loading errors have occurred. const loadingError = img.naturalHeight === 0; // Report status after a tick, to make sure event listeners are registered. if (loadingError) { tick().then(onImageError); } else { tick().then(onImageLoaded); } return {}; } // Image has not been loaded yet, report status with event listeners. img.addEventListener('load', onImageLoaded, { once: true }); img.addEventListener('error', onImageError, { once: true }); return { destroy() { img.removeEventListener('load', onImageLoaded); img.removeEventListener('error', onImageError); } }; }